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"
4125753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy#include "ResponseCode.h"
425af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
435af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include "SoftapController.h"
445af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
4578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriffstatic const char HOSTAPD_CONF_FILE[]    = "/data/misc/wifi/hostapd.conf";
4625753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiystatic const char HOSTAPD_BIN_FILE[]    = "/system/bin/hostapd";
4778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
4825753d500d9ef6ee04dad43ffa27287a6dc959acSasha LevitskiySoftapController::SoftapController()
4925753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    : mPid(0) {}
505af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
515af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtSoftapController::~SoftapController() {
5284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt}
5384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
545af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::startSoftap() {
555af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    pid_t pid = 1;
565af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
575af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (mPid) {
5825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        ALOGE("SoftAP is already running");
5925753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::SoftapStatusResult;
6084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
617e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff
62389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    if ((pid = fork()) < 0) {
635ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("fork failed (%s)", strerror(errno));
6425753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::ServiceStartFailed;
655af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
667e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff
675af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (!pid) {
6801e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt        ensure_entropy_file_exists();
6925753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        if (execl(HOSTAPD_BIN_FILE, HOSTAPD_BIN_FILE,
7001e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt                  "-e", WIFI_ENTROPY_FILE,
7178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                  HOSTAPD_CONF_FILE, (char *) NULL)) {
725ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("execl failed (%s)", strerror(errno));
73389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        }
7425753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        ALOGE("SoftAP failed to start");
7525753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::ServiceStartFailed;
765af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else {
777e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff        mPid = pid;
7825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        ALOGD("SoftAP started successfully");
797e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff        usleep(AP_BSS_START_DELAY);
805af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
8125753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    return ResponseCode::SoftapStatusResult;
825af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
835af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
845af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::stopSoftap() {
8584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
865af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (mPid == 0) {
8725753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        ALOGE("SoftAP is not running");
8825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::SoftapStatusResult;
895af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
90389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt
9125753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    ALOGD("Stopping the SoftAP service...");
92389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    kill(mPid, SIGTERM);
93389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    waitpid(mPid, NULL, 0);
947e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff
955af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    mPid = 0;
9625753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    ALOGD("SoftAP stopped successfully");
973df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt    usleep(AP_BSS_STOP_DELAY);
9825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    return ResponseCode::SoftapStatusResult;
995af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
1005af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
1015af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtbool SoftapController::isSoftapStarted() {
10225753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    return (mPid != 0);
1035af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
1045af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
10584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt/*
10684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt * Arguments:
10725753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy *  argv[2] - wlan interface
10825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy *  argv[3] - SSID
109eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt *  argv[4] - Broadcast/Hidden
11085e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt *  argv[5] - Channel
11185e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt *  argv[6] - Security
11285e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt *  argv[7] - Key
11384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt */
1145af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::setSoftap(int argc, char *argv[]) {
115a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root    char psk_str[2*SHA256_DIGEST_LENGTH+1];
11625753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    int ret = ResponseCode::SoftapStatusResult;
11725753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    int i = 0;
11825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    int fd;
119eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt    int hidden = 0;
12085e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt    int channel = AP_CHANNEL_DEFAULT;
121eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt    char *wbuf = NULL;
122eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt    char *fbuf = NULL;
12384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
124eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt    if (argc < 5) {
125eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt        ALOGE("Softap set is missing arguments. Please use:");
12685e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt        ALOGE("softap <wlan iface> <SSID> <hidden/broadcast> <channel> <wpa2?-psk|open> <passphrase>");
12725753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::CommandSyntaxError;
12884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
12984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
130eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt    if (!strcasecmp(argv[4], "hidden"))
131eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt        hidden = 1;
13278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
13385e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt    if (argc >= 5) {
13485e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt        channel = atoi(argv[5]);
13585e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt        if (channel <= 0)
13685e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt            channel = AP_CHANNEL_DEFAULT;
13785e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt    }
13885e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt
13978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    asprintf(&wbuf, "interface=%s\ndriver=nl80211\nctrl_interface="
14085e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt            "/data/misc/wifi/hostapd\nssid=%s\nchannel=%d\nieee80211n=1\n"
141eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt            "hw_mode=g\nignore_broadcast_ssid=%d\n",
14285e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt            argv[2], argv[3], channel, hidden);
14378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
14485e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt    if (argc > 7) {
14585e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt        if (!strcmp(argv[6], "wpa-psk")) {
14685e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt            generatePsk(argv[3], argv[7], psk_str);
14754b75b4e772ac77df141ab077be074bc1c098987Irfan Sheriff            asprintf(&fbuf, "%swpa=1\nwpa_pairwise=TKIP CCMP\nwpa_psk=%s\n", wbuf, psk_str);
14885e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt        } else if (!strcmp(argv[6], "wpa2-psk")) {
14985e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt            generatePsk(argv[3], argv[7], psk_str);
15054b75b4e772ac77df141ab077be074bc1c098987Irfan Sheriff            asprintf(&fbuf, "%swpa=2\nrsn_pairwise=CCMP\nwpa_psk=%s\n", wbuf, psk_str);
15185e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt        } else if (!strcmp(argv[6], "open")) {
1520b73d66921bd70ed94b2501c67d444a1ba2e4ed4Dmitry Shmidt            asprintf(&fbuf, "%s", wbuf);
153eb59b57432c65b034d1360803c881c08a318c4d0Dmitry Shmidt        }
15485e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt    } else if (argc > 6) {
15585e6c5f00bef0e23f81904bc8a430498a545f4f6Dmitry Shmidt        if (!strcmp(argv[6], "open")) {
15678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            asprintf(&fbuf, "%s", wbuf);
15778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        }
15878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    } else {
15978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        asprintf(&fbuf, "%s", wbuf);
16078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
16178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
16243682d9474a2c89ddecc9fcc818df40e4f5424eeRobert Greenwalt    fd = open(HOSTAPD_CONF_FILE, O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW, 0660);
16378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (fd < 0) {
1645ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Cannot update \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
16578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        free(wbuf);
16678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        free(fbuf);
16725753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::OperationFailed;
16878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
16978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (write(fd, fbuf, strlen(fbuf)) < 0) {
1705ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Cannot write to \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
17125753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        ret = ResponseCode::OperationFailed;
17278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
17378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    free(wbuf);
17478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    free(fbuf);
17578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
17678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    /* Note: apparently open can fail to set permissions correctly at times */
177e0644327ffb203e0b45f3192fd888831902e267cRobert Greenwalt    if (fchmod(fd, 0660) < 0) {
1785ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Error changing permissions of %s to 0660: %s",
17978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                HOSTAPD_CONF_FILE, strerror(errno));
180e0644327ffb203e0b45f3192fd888831902e267cRobert Greenwalt        close(fd);
18178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        unlink(HOSTAPD_CONF_FILE);
18225753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::OperationFailed;
18378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
18478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
185e0644327ffb203e0b45f3192fd888831902e267cRobert Greenwalt    if (fchown(fd, AID_SYSTEM, AID_WIFI) < 0) {
1865ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Error changing group ownership of %s to %d: %s",
18778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                HOSTAPD_CONF_FILE, AID_WIFI, strerror(errno));
188e0644327ffb203e0b45f3192fd888831902e267cRobert Greenwalt        close(fd);
18978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        unlink(HOSTAPD_CONF_FILE);
19025753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::OperationFailed;
19178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
19278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
193e0644327ffb203e0b45f3192fd888831902e267cRobert Greenwalt    close(fd);
19484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return ret;
1955af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
19631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
19731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt/*
19831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt * Arguments:
19931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt *	argv[2] - interface name
20025753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy *	argv[3] - AP or P2P or STA
20131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt */
20231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidtint SoftapController::fwReloadSoftap(int argc, char *argv[])
20331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt{
20425753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    int i = 0;
20525753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    char *fwpath = NULL;
20631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
20731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (argc < 4) {
20825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        ALOGE("SoftAP fwreload is missing arguments. Please use: softap <wlan iface> <AP|P2P|STA>");
20925753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::CommandSyntaxError;
21031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
21131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
21231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (strcmp(argv[3], "AP") == 0) {
213fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_AP);
21454cf7fda69c3c442e7d2ac370a9c942fdb38dcd7Dmitry Shmidt    } else if (strcmp(argv[3], "P2P") == 0) {
21554cf7fda69c3c442e7d2ac370a9c942fdb38dcd7Dmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_P2P);
21625753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    } else if (strcmp(argv[3], "STA") == 0) {
217fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_STA);
21831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
219fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt    if (!fwpath)
22025753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::CommandParameterError;
22125753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    if (wifi_change_fw_path((const char *)fwpath)) {
22225753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        ALOGE("Softap fwReload failed");
22325753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        return ResponseCode::OperationFailed;
22431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
22531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    else {
2267b984e3f7e724f8a3547a707210319f3d479f261Steve Block        ALOGD("Softap fwReload - Ok");
22731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
22825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    return ResponseCode::SoftapStatusResult;
22931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt}
230666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt
23125753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiyvoid SoftapController::generatePsk(char *ssid, char *passphrase, char *psk_str) {
23225753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    unsigned char psk[SHA256_DIGEST_LENGTH];
23325753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    int j;
23425753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    // Use the PKCS#5 PBKDF2 with 4096 iterations
23525753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    PKCS5_PBKDF2_HMAC_SHA1(passphrase, strlen(passphrase),
23625753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy            reinterpret_cast<const unsigned char *>(ssid), strlen(ssid),
23725753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy            4096, SHA256_DIGEST_LENGTH, psk);
23825753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    for (j=0; j < SHA256_DIGEST_LENGTH; j++) {
23925753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy        sprintf(&psk_str[j*2], "%02x", psk[j]);
24025753d500d9ef6ee04dad43ffa27287a6dc959acSasha Levitskiy    }
241666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt}
242