SoftapController.cpp revision 78dcb76aff7d3b9458374832a79688d36901127f
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>
20ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#include <string.h>
215af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
225af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <sys/socket.h>
235af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <sys/stat.h>
24ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#include <sys/ioctl.h>
255af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <sys/types.h>
265af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <sys/wait.h>
275af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
285af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <netinet/in.h>
295af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <arpa/inet.h>
305af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
3184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt#include <linux/wireless.h>
3284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
33a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root#include <openssl/evp.h>
34a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root#include <openssl/sha.h>
35a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root
365af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#define LOG_TAG "SoftapController"
375af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <cutils/log.h>
38389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#include <netutils/ifc.h>
3978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff#include <private/android_filesystem_config.h>
40fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt#include "wifi.h"
415af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
425af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include "SoftapController.h"
435af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
4478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriffstatic const char HOSTAPD_CONF_FILE[]    = "/data/misc/wifi/hostapd.conf";
4578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
465af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtSoftapController::SoftapController() {
475af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    mPid = 0;
4884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    mSock = socket(AF_INET, SOCK_DGRAM, 0);
4984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock < 0)
5084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        LOGE("Failed to open socket");
5184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    memset(mIface, 0, sizeof(mIface));
525af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
535af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
545af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtSoftapController::~SoftapController() {
5584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock >= 0)
5684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        close(mSock);
5784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt}
5884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
59666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidtint SoftapController::setCommand(char *iface, const char *fname, unsigned buflen) {
60389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#ifdef HAVE_HOSTAPD
61389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    return 0;
62389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#else
636665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    char tBuf[SOFTAP_MAX_BUFFER_SIZE];
6484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    struct iwreq wrq;
6584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    struct iw_priv_args *priv_ptr;
66fbd11c41aeb535723b78a61087fb436e64891055jmzhu    int i, j, ret;
67fbd11c41aeb535723b78a61087fb436e64891055jmzhu    int cmd = 0, sub_cmd = 0;
6884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
6984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    strncpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name));
706665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    wrq.u.data.pointer = tBuf;
716665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    wrq.u.data.length = sizeof(tBuf) / sizeof(struct iw_priv_args);
7284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    wrq.u.data.flags = 0;
7384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if ((ret = ioctl(mSock, SIOCGIWPRIV, &wrq)) < 0) {
7484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        LOGE("SIOCGIPRIV failed: %d", ret);
7584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return ret;
7684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
77fbd11c41aeb535723b78a61087fb436e64891055jmzhu
7884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    priv_ptr = (struct iw_priv_args *)wrq.u.data.pointer;
79fbd11c41aeb535723b78a61087fb436e64891055jmzhu    for(i=0; i < wrq.u.data.length;i++) {
80fbd11c41aeb535723b78a61087fb436e64891055jmzhu        if (strcmp(priv_ptr[i].name, fname) == 0) {
81fbd11c41aeb535723b78a61087fb436e64891055jmzhu            cmd = priv_ptr[i].cmd;
82fbd11c41aeb535723b78a61087fb436e64891055jmzhu            break;
83fbd11c41aeb535723b78a61087fb436e64891055jmzhu        }
8484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
85c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt
86fbd11c41aeb535723b78a61087fb436e64891055jmzhu    if (i == wrq.u.data.length) {
87fbd11c41aeb535723b78a61087fb436e64891055jmzhu        LOGE("iface:%s, fname: %s - function not supported", iface, fname);
886665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        return -1;
896665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    }
906665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt
91fbd11c41aeb535723b78a61087fb436e64891055jmzhu    if (cmd < SIOCDEVPRIVATE) {
92fbd11c41aeb535723b78a61087fb436e64891055jmzhu        for(j=0; j < i; j++) {
93fbd11c41aeb535723b78a61087fb436e64891055jmzhu            if ((priv_ptr[j].set_args == priv_ptr[i].set_args) &&
94fbd11c41aeb535723b78a61087fb436e64891055jmzhu                (priv_ptr[j].get_args == priv_ptr[i].get_args) &&
95fbd11c41aeb535723b78a61087fb436e64891055jmzhu                (priv_ptr[j].name[0] == '\0'))
96fbd11c41aeb535723b78a61087fb436e64891055jmzhu                break;
97fbd11c41aeb535723b78a61087fb436e64891055jmzhu        }
98fbd11c41aeb535723b78a61087fb436e64891055jmzhu        if (j == i) {
99fbd11c41aeb535723b78a61087fb436e64891055jmzhu            LOGE("iface:%s, fname: %s - invalid private ioctl", iface, fname);
100fbd11c41aeb535723b78a61087fb436e64891055jmzhu            return -1;
101fbd11c41aeb535723b78a61087fb436e64891055jmzhu        }
102fbd11c41aeb535723b78a61087fb436e64891055jmzhu        sub_cmd = cmd;
103fbd11c41aeb535723b78a61087fb436e64891055jmzhu        cmd = priv_ptr[j].cmd;
104fbd11c41aeb535723b78a61087fb436e64891055jmzhu    }
105fbd11c41aeb535723b78a61087fb436e64891055jmzhu
1066665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    strncpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name));
107666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    if ((buflen == 0) && (*mBuf != 0))
1086665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        wrq.u.data.length = strlen(mBuf) + 1;
1096665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    else
110666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        wrq.u.data.length = buflen;
1116665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    wrq.u.data.pointer = mBuf;
112fbd11c41aeb535723b78a61087fb436e64891055jmzhu    wrq.u.data.flags = sub_cmd;
113fbd11c41aeb535723b78a61087fb436e64891055jmzhu    ret = ioctl(mSock, cmd, &wrq);
1146665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    return ret;
115389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#endif
1166665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt}
1176665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt
1186665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidtint SoftapController::startDriver(char *iface) {
1196665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ret;
1206665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt
121c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    if (mSock < 0) {
122a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt        LOGE("Softap driver start - failed to open socket");
123c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        return -1;
124c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    }
125c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    if (!iface || (iface[0] == '\0')) {
126a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt        LOGD("Softap driver start - wrong interface");
127c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        iface = mIface;
128c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    }
1296665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt
1306665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    *mBuf = 0;
1316665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    ret = setCommand(iface, "START");
132389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    if (ret < 0) {
133389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        LOGE("Softap driver start: %d", ret);
134389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        return ret;
135389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    }
136389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#ifdef HAVE_HOSTAPD
137389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    ifc_init();
138389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    ret = ifc_up(iface);
139389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    ifc_close();
140389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#endif
141a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt    usleep(AP_DRIVER_START_DELAY);
142a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt    LOGD("Softap driver start: %d", ret);
143c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    return ret;
144c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt}
145c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt
146c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidtint SoftapController::stopDriver(char *iface) {
1476665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ret;
148c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt
149c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    if (mSock < 0) {
150a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt        LOGE("Softap driver stop - failed to open socket");
151c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        return -1;
152c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    }
153c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    if (!iface || (iface[0] == '\0')) {
154a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt        LOGD("Softap driver stop - wrong interface");
155c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        iface = mIface;
156c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    }
1576665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    *mBuf = 0;
158389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#ifdef HAVE_HOSTAPD
159389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    ifc_init();
160389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    ret = ifc_down(iface);
161389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    ifc_close();
162389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    if (ret < 0) {
163389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        LOGE("Softap %s down: %d", iface, ret);
164389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    }
165389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#endif
1666665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    ret = setCommand(iface, "STOP");
167a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt    LOGD("Softap driver stop: %d", ret);
168c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    return ret;
169c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt}
170c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt
1715af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::startSoftap() {
1725af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    pid_t pid = 1;
1736665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ret = 0;
1745af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
1755af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (mPid) {
1765af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        LOGE("Softap already started");
177a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt        return 0;
1785af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
17984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock < 0) {
180c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        LOGE("Softap startap - failed to open socket");
18184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
18284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
183389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#ifdef HAVE_HOSTAPD
184389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    if ((pid = fork()) < 0) {
1855af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        LOGE("fork failed (%s)", strerror(errno));
1865af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return -1;
1875af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
1885af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#endif
1895af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (!pid) {
190389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#ifdef HAVE_HOSTAPD
19178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        if (execl("/system/bin/hostapd", "/system/bin/hostapd",
19278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                  HOSTAPD_CONF_FILE, (char *) NULL)) {
193389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt           LOGE("execl failed (%s)", strerror(errno));
194389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        }
195389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#endif
196389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        LOGE("Should never get here!");
197389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        return -1;
1985af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else {
1996665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        *mBuf = 0;
2006665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        ret = setCommand(mIface, "AP_BSS_START");
20184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        if (ret) {
202c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt            LOGE("Softap startap - failed: %d", ret);
20384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        }
20484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        else {
20584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt           mPid = pid;
206c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt           LOGD("Softap startap - Ok");
2073df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt           usleep(AP_BSS_START_DELAY);
20884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        }
2095af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
21084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return ret;
2115af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2125af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
2135af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2145af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::stopSoftap() {
2156665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ret;
21684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
2175af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (mPid == 0) {
2185af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        LOGE("Softap already stopped");
2195af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return 0;
2205af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
221389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt
222389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#ifdef HAVE_HOSTAPD
223389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    LOGD("Stopping Softap service");
224389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    kill(mPid, SIGTERM);
225389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    waitpid(mPid, NULL, 0);
226389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#endif
22784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock < 0) {
228c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        LOGE("Softap stopap - failed to open socket");
22984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
23084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
2316665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    *mBuf = 0;
2326665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    ret = setCommand(mIface, "AP_BSS_STOP");
2335af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    mPid = 0;
23484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    LOGD("Softap service stopped: %d", ret);
2353df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt    usleep(AP_BSS_STOP_DELAY);
23684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return ret;
2375af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
2385af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2395af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtbool SoftapController::isSoftapStarted() {
2405af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    return (mPid != 0 ? true : false);
2415af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
2425af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2437977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidtint SoftapController::addParam(int pos, const char *cmd, const char *arg)
2447977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt{
2457977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (pos < 0)
2467977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        return pos;
2477977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if ((unsigned)(pos + strlen(cmd) + strlen(arg) + 1) >= sizeof(mBuf)) {
2487977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        LOGE("Command line is too big");
2497977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        return -1;
2507977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
2517977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    pos += sprintf(&mBuf[pos], "%s=%s,", cmd, arg);
2527977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    return pos;
2537977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt}
2547977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
25584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt/*
25684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt * Arguments:
25784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt *      argv[2] - wlan interface
25884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt *      argv[3] - softap interface
2597977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *      argv[4] - SSID
2607977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[5] - Security
2617977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[6] - Key
2627977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[7] - Channel
2637977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[8] - Preamble
2647977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[9] - Max SCB
26584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt */
2665af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::setSoftap(int argc, char *argv[]) {
267a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root    char psk_str[2*SHA256_DIGEST_LENGTH+1];
26878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    int ret = 0, i = 0, fd;
2696665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    char *ssid, *iface;
27084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
27184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock < 0) {
2727977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        LOGE("Softap set - failed to open socket");
27384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
27484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
27584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (argc < 4) {
2767977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        LOGE("Softap set - missing arguments");
27784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
27884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
27984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
28084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    strncpy(mIface, argv[3], sizeof(mIface));
2816665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    iface = argv[2];
2827977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
28378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff#ifdef HAVE_HOSTAPD
28478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    char *wbuf = NULL;
28578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    char *fbuf = NULL;
28678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
28778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (argc > 4) {
28878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        ssid = argv[4];
28978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    } else {
29078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        ssid = (char *)"AndroidAP";
29178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
29278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
29378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    asprintf(&wbuf, "interface=%s\ndriver=nl80211\nctrl_interface="
29478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            "/data/misc/wifi/hostapd\nssid=%s\nchannel=6\n", iface, ssid);
29578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
29678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (argc > 5) {
29778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        if (!strcmp(argv[5], "wpa-psk")) {
29878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            generatePsk(ssid, argv[6], psk_str);
29978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            asprintf(&fbuf, "%swpa=1\nwpa_psk=%s\n", wbuf, psk_str);
30078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        } else if (!strcmp(argv[5], "wpa2-psk")) {
30178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            generatePsk(ssid, argv[6], psk_str);
30278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            asprintf(&fbuf, "%swpa=2\nwpa_psk=%s\n", wbuf, psk_str);
30378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        } else if (!strcmp(argv[5], "open")) {
30478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            asprintf(&fbuf, "%s", wbuf);
30578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        }
30678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    } else {
30778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        asprintf(&fbuf, "%s", wbuf);
30878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
30978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
31078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    fd = open(HOSTAPD_CONF_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0660);
31178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (fd < 0) {
31278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        LOGE("Cannot update \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
31378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        free(wbuf);
31478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        free(fbuf);
31578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        return -1;
31678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
31778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (write(fd, fbuf, strlen(fbuf)) < 0) {
31878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        LOGE("Cannot write to \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
31978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        ret = -1;
32078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
32178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    close(fd);
32278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    free(wbuf);
32378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    free(fbuf);
32478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
32578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    /* Note: apparently open can fail to set permissions correctly at times */
32678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (chmod(HOSTAPD_CONF_FILE, 0660) < 0) {
32778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        LOGE("Error changing permissions of %s to 0660: %s",
32878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                HOSTAPD_CONF_FILE, strerror(errno));
32978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        unlink(HOSTAPD_CONF_FILE);
33078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        return -1;
33178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
33278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
33378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (chown(HOSTAPD_CONF_FILE, AID_SYSTEM, AID_WIFI) < 0) {
33478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        LOGE("Error changing group ownership of %s to %d: %s",
33578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                HOSTAPD_CONF_FILE, AID_WIFI, strerror(errno));
33678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        unlink(HOSTAPD_CONF_FILE);
33778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        return -1;
33878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
33978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
34078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff#else
3417977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    /* Create command line */
3427977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    i = addParam(i, "ASCII_CMD", "AP_CFG");
3437977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 4) {
344321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt        ssid = argv[4];
3457977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
346321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt        ssid = (char *)"AndroidAP";
3477977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
348321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt    i = addParam(i, "SSID", ssid);
3497977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 5) {
3507977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "SEC", argv[5]);
3517977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3527977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "SEC", "open");
3537977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3547977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 6) {
35578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        generatePsk(ssid, argv[6], psk_str);
356321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt        i = addParam(i, "KEY", psk_str);
3577977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3587977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "KEY", "12345678");
3597977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3607977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 7) {
3617977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "CHANNEL", argv[7]);
3627977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3637977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "CHANNEL", "6");
3647977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3657977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 8) {
3667977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "PREAMBLE", argv[8]);
3677977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3687977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "PREAMBLE", "0");
3697977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3707977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 9) {
3717977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "MAX_SCB", argv[9]);
3727977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3737977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "MAX_SCB", "8");
3747977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3757977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if ((i < 0) || ((unsigned)(i + 4) >= sizeof(mBuf))) {
3767977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        LOGE("Softap set - command is too big");
3777977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        return i;
37884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
3797977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    sprintf(&mBuf[i], "END");
38084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
38184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry 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"); */
3826665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    ret = setCommand(iface, "AP_SET_CFG");
38384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (ret) {
38484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        LOGE("Softap set - failed: %d", ret);
38584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
38684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    else {
38784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        LOGD("Softap set - Ok");
3883df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt        usleep(AP_SET_CFG_DELAY);
38984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
39078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff#endif
39184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return ret;
3925af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
39331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
39478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriffvoid SoftapController::generatePsk(char *ssid, char *passphrase, char *psk_str) {
39578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    unsigned char psk[SHA256_DIGEST_LENGTH];
39678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    int j;
39778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    // Use the PKCS#5 PBKDF2 with 4096 iterations
39878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    PKCS5_PBKDF2_HMAC_SHA1(passphrase, strlen(passphrase),
39978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            reinterpret_cast<const unsigned char *>(ssid), strlen(ssid),
40078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            4096, SHA256_DIGEST_LENGTH, psk);
40178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    for (j=0; j < SHA256_DIGEST_LENGTH; j++) {
40278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        sprintf(&psk_str[j<<1], "%02x", psk[j]);
40378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
40478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    psk_str[j<<1] = '\0';
40578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff}
40678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
40778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
40831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt/*
40931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt * Arguments:
41031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt *	argv[2] - interface name
41131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt *	argv[3] - AP or STA
41231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt */
41331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidtint SoftapController::fwReloadSoftap(int argc, char *argv[])
41431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt{
4156665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ret, i = 0;
41631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    char *iface;
417fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt    char *fwpath;
41831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
41931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (mSock < 0) {
42031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        LOGE("Softap fwrealod - failed to open socket");
42131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        return -1;
42231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
42331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (argc < 4) {
42431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        LOGE("Softap fwreload - missing arguments");
42531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        return -1;
42631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
42731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
42831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    iface = argv[2];
42931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
43031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (strcmp(argv[3], "AP") == 0) {
431fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_AP);
43231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    } else {
433fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_STA);
43431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
435fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt    if (!fwpath)
436fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        return -1;
437389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#ifdef HAVE_HOSTAPD
438389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    ret = wifi_change_fw_path((const char *)fwpath);
439389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#else
440fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt    sprintf(mBuf, "FW_PATH=%s", fwpath);
4416665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    ret = setCommand(iface, "WL_FW_RELOAD");
442389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#endif
44331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (ret) {
44431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        LOGE("Softap fwReload - failed: %d", ret);
44531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
44631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    else {
44731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        LOGD("Softap fwReload - Ok");
44831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
44931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    return ret;
45031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt}
451666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt
452666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidtint SoftapController::clientsSoftap(char **retbuf)
453666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt{
454666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    int ret;
455666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt
456666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    if (mSock < 0) {
457666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        LOGE("Softap clients - failed to open socket");
458666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        return -1;
459666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    }
460666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    *mBuf = 0;
461666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    ret = setCommand(mIface, "AP_GET_STA_LIST", SOFTAP_MAX_BUFFER_SIZE);
462666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    if (ret) {
463666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        LOGE("Softap clients - failed: %d", ret);
464666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    } else {
465666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        asprintf(retbuf, "Softap clients:%s", mBuf);
466666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        LOGD("Softap clients:%s", mBuf);
467666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    }
468666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    return ret;
469666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt}
470