SoftapController.cpp revision 54b75b4e772ac77df141ab077be074bc1c098987
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
19101e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt        ensure_entropy_file_exists();
19278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        if (execl("/system/bin/hostapd", "/system/bin/hostapd",
19301e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt                  "-e", WIFI_ENTROPY_FILE,
19478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                  HOSTAPD_CONF_FILE, (char *) NULL)) {
19501e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt            LOGE("execl failed (%s)", strerror(errno));
196389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        }
197389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#endif
198389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        LOGE("Should never get here!");
199389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        return -1;
2005af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else {
2016665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        *mBuf = 0;
2026665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        ret = setCommand(mIface, "AP_BSS_START");
20384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        if (ret) {
204c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt            LOGE("Softap startap - failed: %d", ret);
20584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        }
20684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        else {
20784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt           mPid = pid;
208c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt           LOGD("Softap startap - Ok");
2093df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt           usleep(AP_BSS_START_DELAY);
21084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        }
2115af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
21284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return ret;
2135af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2145af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
2155af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2165af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::stopSoftap() {
2176665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ret;
21884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
2195af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (mPid == 0) {
2205af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        LOGE("Softap already stopped");
2215af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return 0;
2225af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
223389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt
224389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#ifdef HAVE_HOSTAPD
225389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    LOGD("Stopping Softap service");
226389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    kill(mPid, SIGTERM);
227389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    waitpid(mPid, NULL, 0);
228389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#endif
22984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock < 0) {
230c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        LOGE("Softap stopap - failed to open socket");
23184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
23284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
2336665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    *mBuf = 0;
2346665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    ret = setCommand(mIface, "AP_BSS_STOP");
2355af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    mPid = 0;
23684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    LOGD("Softap service stopped: %d", ret);
2373df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt    usleep(AP_BSS_STOP_DELAY);
23884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return ret;
2395af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
2405af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2415af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtbool SoftapController::isSoftapStarted() {
2425af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    return (mPid != 0 ? true : false);
2435af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
2445af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2457977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidtint SoftapController::addParam(int pos, const char *cmd, const char *arg)
2467977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt{
2477977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (pos < 0)
2487977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        return pos;
2497977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if ((unsigned)(pos + strlen(cmd) + strlen(arg) + 1) >= sizeof(mBuf)) {
2507977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        LOGE("Command line is too big");
2517977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        return -1;
2527977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
2537977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    pos += sprintf(&mBuf[pos], "%s=%s,", cmd, arg);
2547977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    return pos;
2557977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt}
2567977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
25784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt/*
25884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt * Arguments:
25984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt *      argv[2] - wlan interface
26084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt *      argv[3] - softap interface
2617977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *      argv[4] - SSID
2627977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[5] - Security
2637977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[6] - Key
2647977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[7] - Channel
2657977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[8] - Preamble
2667977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt *	argv[9] - Max SCB
26784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt */
2685af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::setSoftap(int argc, char *argv[]) {
269a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root    char psk_str[2*SHA256_DIGEST_LENGTH+1];
27078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    int ret = 0, i = 0, fd;
2716665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    char *ssid, *iface;
27284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
27384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock < 0) {
2747977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        LOGE("Softap set - failed to open socket");
27584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
27684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
27784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (argc < 4) {
2787977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        LOGE("Softap set - missing arguments");
27984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
28084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
28184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
28284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    strncpy(mIface, argv[3], sizeof(mIface));
2836665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    iface = argv[2];
2847977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
28578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff#ifdef HAVE_HOSTAPD
28678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    char *wbuf = NULL;
28778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    char *fbuf = NULL;
28878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
28978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (argc > 4) {
29078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        ssid = argv[4];
29178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    } else {
29278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        ssid = (char *)"AndroidAP";
29378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
29478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
29578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    asprintf(&wbuf, "interface=%s\ndriver=nl80211\nctrl_interface="
29678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            "/data/misc/wifi/hostapd\nssid=%s\nchannel=6\n", iface, ssid);
29778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
29878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (argc > 5) {
29978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        if (!strcmp(argv[5], "wpa-psk")) {
30078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            generatePsk(ssid, argv[6], psk_str);
30154b75b4e772ac77df141ab077be074bc1c098987Irfan Sheriff            asprintf(&fbuf, "%swpa=1\nwpa_pairwise=TKIP CCMP\nwpa_psk=%s\n", wbuf, psk_str);
30278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        } else if (!strcmp(argv[5], "wpa2-psk")) {
30378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            generatePsk(ssid, argv[6], psk_str);
30454b75b4e772ac77df141ab077be074bc1c098987Irfan Sheriff            asprintf(&fbuf, "%swpa=2\nrsn_pairwise=CCMP\nwpa_psk=%s\n", wbuf, psk_str);
30578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        } else if (!strcmp(argv[5], "open")) {
30678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            asprintf(&fbuf, "%s", wbuf);
30778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        }
30878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    } else {
30978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        asprintf(&fbuf, "%s", wbuf);
31078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
31178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
31278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    fd = open(HOSTAPD_CONF_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0660);
31378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (fd < 0) {
31478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        LOGE("Cannot update \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
31578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        free(wbuf);
31678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        free(fbuf);
31778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        return -1;
31878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
31978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (write(fd, fbuf, strlen(fbuf)) < 0) {
32078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        LOGE("Cannot write to \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
32178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        ret = -1;
32278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
32378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    close(fd);
32478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    free(wbuf);
32578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    free(fbuf);
32678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
32778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    /* Note: apparently open can fail to set permissions correctly at times */
32878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (chmod(HOSTAPD_CONF_FILE, 0660) < 0) {
32978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        LOGE("Error changing permissions of %s to 0660: %s",
33078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                HOSTAPD_CONF_FILE, strerror(errno));
33178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        unlink(HOSTAPD_CONF_FILE);
33278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        return -1;
33378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
33478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
33578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (chown(HOSTAPD_CONF_FILE, AID_SYSTEM, AID_WIFI) < 0) {
33678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        LOGE("Error changing group ownership of %s to %d: %s",
33778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                HOSTAPD_CONF_FILE, AID_WIFI, strerror(errno));
33878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        unlink(HOSTAPD_CONF_FILE);
33978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        return -1;
34078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
34178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
34278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff#else
3437977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    /* Create command line */
3447977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    i = addParam(i, "ASCII_CMD", "AP_CFG");
3457977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 4) {
346321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt        ssid = argv[4];
3477977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
348321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt        ssid = (char *)"AndroidAP";
3497977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
350321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt    i = addParam(i, "SSID", ssid);
3517977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 5) {
3527977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "SEC", argv[5]);
3537977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3547977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "SEC", "open");
3557977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3567977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 6) {
35778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        generatePsk(ssid, argv[6], psk_str);
358321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt        i = addParam(i, "KEY", psk_str);
3597977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3607977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "KEY", "12345678");
3617977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3627977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 7) {
3637977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "CHANNEL", argv[7]);
3647977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3657977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "CHANNEL", "6");
3667977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3677977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 8) {
3687977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "PREAMBLE", argv[8]);
3697977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3707977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "PREAMBLE", "0");
3717977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3727977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if (argc > 9) {
3737977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "MAX_SCB", argv[9]);
3747977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    } else {
3757977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        i = addParam(i, "MAX_SCB", "8");
3767977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    }
3777977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    if ((i < 0) || ((unsigned)(i + 4) >= sizeof(mBuf))) {
3787977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        LOGE("Softap set - command is too big");
3797977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        return i;
38084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
3817977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    sprintf(&mBuf[i], "END");
38284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
38384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry 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"); */
3846665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    ret = setCommand(iface, "AP_SET_CFG");
38584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (ret) {
38684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        LOGE("Softap set - failed: %d", ret);
38784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
38884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    else {
38984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        LOGD("Softap set - Ok");
3903df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt        usleep(AP_SET_CFG_DELAY);
39184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
39278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff#endif
39384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return ret;
3945af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
39531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
39678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriffvoid SoftapController::generatePsk(char *ssid, char *passphrase, char *psk_str) {
39778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    unsigned char psk[SHA256_DIGEST_LENGTH];
39878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    int j;
39978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    // Use the PKCS#5 PBKDF2 with 4096 iterations
40078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    PKCS5_PBKDF2_HMAC_SHA1(passphrase, strlen(passphrase),
40178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            reinterpret_cast<const unsigned char *>(ssid), strlen(ssid),
40278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            4096, SHA256_DIGEST_LENGTH, psk);
40378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    for (j=0; j < SHA256_DIGEST_LENGTH; j++) {
40478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        sprintf(&psk_str[j<<1], "%02x", psk[j]);
40578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
40678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    psk_str[j<<1] = '\0';
40778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff}
40878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
40978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
41031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt/*
41131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt * Arguments:
41231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt *	argv[2] - interface name
41331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt *	argv[3] - AP or STA
41431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt */
41531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidtint SoftapController::fwReloadSoftap(int argc, char *argv[])
41631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt{
4176665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ret, i = 0;
41831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    char *iface;
419fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt    char *fwpath;
42031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
42131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (mSock < 0) {
42231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        LOGE("Softap fwrealod - failed to open socket");
42331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        return -1;
42431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
42531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (argc < 4) {
42631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        LOGE("Softap fwreload - missing arguments");
42731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        return -1;
42831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
42931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
43031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    iface = argv[2];
43131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
43231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (strcmp(argv[3], "AP") == 0) {
433fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_AP);
43454cf7fda69c3c442e7d2ac370a9c942fdb38dcd7Dmitry Shmidt    } else if (strcmp(argv[3], "P2P") == 0) {
43554cf7fda69c3c442e7d2ac370a9c942fdb38dcd7Dmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_P2P);
43631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    } else {
437fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_STA);
43831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
439fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt    if (!fwpath)
440fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        return -1;
441389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#ifdef HAVE_HOSTAPD
442389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    ret = wifi_change_fw_path((const char *)fwpath);
443389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#else
444fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt    sprintf(mBuf, "FW_PATH=%s", fwpath);
4456665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    ret = setCommand(iface, "WL_FW_RELOAD");
446389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt#endif
44731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (ret) {
44831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        LOGE("Softap fwReload - failed: %d", ret);
44931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
45031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    else {
45131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        LOGD("Softap fwReload - Ok");
45231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
45331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    return ret;
45431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt}
455666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt
456666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidtint SoftapController::clientsSoftap(char **retbuf)
457666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt{
458666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    int ret;
459666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt
460666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    if (mSock < 0) {
461666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        LOGE("Softap clients - failed to open socket");
462666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        return -1;
463666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    }
464666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    *mBuf = 0;
465666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    ret = setCommand(mIface, "AP_GET_STA_LIST", SOFTAP_MAX_BUFFER_SIZE);
466666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    if (ret) {
467666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        LOGE("Softap clients - failed: %d", ret);
468666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    } else {
469666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        asprintf(retbuf, "Softap clients:%s", mBuf);
470666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        LOGD("Softap clients:%s", mBuf);
471666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    }
472666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    return ret;
473666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt}
474