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)
505ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Failed to open socket");
515af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
525af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
535af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtSoftapController::~SoftapController() {
5484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock >= 0)
5584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        close(mSock);
5684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt}
5784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
585af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::startSoftap() {
595af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    pid_t pid = 1;
606665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ret = 0;
615af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
625af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (mPid) {
635ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Softap already started");
64a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt        return 0;
655af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
6684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock < 0) {
675ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Softap startap - failed to open socket");
6884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
6984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
707e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff
71389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    if ((pid = fork()) < 0) {
725ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("fork failed (%s)", strerror(errno));
735af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return -1;
745af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
757e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff
765af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (!pid) {
7701e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt        ensure_entropy_file_exists();
7878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        if (execl("/system/bin/hostapd", "/system/bin/hostapd",
7901e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt                  "-e", WIFI_ENTROPY_FILE,
8078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                  HOSTAPD_CONF_FILE, (char *) NULL)) {
815ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("execl failed (%s)", strerror(errno));
82389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        }
835ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Should never get here!");
84389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        return -1;
855af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    } else {
867e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff        mPid = pid;
877e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff        ALOGD("Softap startap - Ok");
887e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff        usleep(AP_BSS_START_DELAY);
895af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
9084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return ret;
915af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
925af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
935af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
945af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::stopSoftap() {
9584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
965af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (mPid == 0) {
975ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Softap already stopped");
985af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return 0;
995af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
100389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt
1017b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Stopping Softap service");
102389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    kill(mPid, SIGTERM);
103389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    waitpid(mPid, NULL, 0);
1047e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff
10584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock < 0) {
1065ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Softap stopap - failed to open socket");
10784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
10884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
1095af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    mPid = 0;
1107e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff    ALOGD("Softap service stopped");
1113df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt    usleep(AP_BSS_STOP_DELAY);
1127e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff    return 0;
1135af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
1145af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
1155af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtbool SoftapController::isSoftapStarted() {
1165af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    return (mPid != 0 ? true : false);
1175af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
1185af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
11984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt/*
12084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt * Arguments:
12184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt *      argv[2] - wlan interface
1227e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff *      argv[3] - SSID
1237e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff *	argv[4] - Security
1247e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff *	argv[5] - Key
1257e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff *	argv[6] - Channel
1267e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff *	argv[7] - Preamble
1277e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff *	argv[8] - Max SCB
12884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt */
1295af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::setSoftap(int argc, char *argv[]) {
130a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root    char psk_str[2*SHA256_DIGEST_LENGTH+1];
13178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    int ret = 0, i = 0, fd;
1326665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    char *ssid, *iface;
13384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
13484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (mSock < 0) {
1355ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Softap set - failed to open socket");
13684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
13784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
13884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    if (argc < 4) {
1395ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Softap set - missing arguments");
14084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        return -1;
14184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    }
14284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
1436665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    iface = argv[2];
1447977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
14578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    char *wbuf = NULL;
14678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    char *fbuf = NULL;
14778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
1487e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff    if (argc > 3) {
1497e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff        ssid = argv[3];
15078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    } else {
15178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        ssid = (char *)"AndroidAP";
15278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
15378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
15478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    asprintf(&wbuf, "interface=%s\ndriver=nl80211\nctrl_interface="
155093e3c70de6caa21cc004db868fe2a9c1055661aDmitry Shmidt            "/data/misc/wifi/hostapd\nssid=%s\nchannel=6\nieee80211n=1\n",
156fa81a805da643421a5bcb182e7860824532b2776Dmitry Shmidt            iface, ssid);
15778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
1587e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff    if (argc > 4) {
1597e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff        if (!strcmp(argv[4], "wpa-psk")) {
1607e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff            generatePsk(ssid, argv[5], psk_str);
16154b75b4e772ac77df141ab077be074bc1c098987Irfan Sheriff            asprintf(&fbuf, "%swpa=1\nwpa_pairwise=TKIP CCMP\nwpa_psk=%s\n", wbuf, psk_str);
1627e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff        } else if (!strcmp(argv[4], "wpa2-psk")) {
1637e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff            generatePsk(ssid, argv[5], psk_str);
16454b75b4e772ac77df141ab077be074bc1c098987Irfan Sheriff            asprintf(&fbuf, "%swpa=2\nrsn_pairwise=CCMP\nwpa_psk=%s\n", wbuf, psk_str);
1657e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff        } else if (!strcmp(argv[4], "open")) {
16678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            asprintf(&fbuf, "%s", wbuf);
16778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        }
16878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    } else {
16978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        asprintf(&fbuf, "%s", wbuf);
17078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
17178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
17278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    fd = open(HOSTAPD_CONF_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0660);
17378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (fd < 0) {
1745ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Cannot update \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
17578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        free(wbuf);
17678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        free(fbuf);
17778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        return -1;
17878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
17978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (write(fd, fbuf, strlen(fbuf)) < 0) {
1805ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Cannot write to \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
18178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        ret = -1;
18278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
18378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    close(fd);
18478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    free(wbuf);
18578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    free(fbuf);
18678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
18778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    /* Note: apparently open can fail to set permissions correctly at times */
18878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (chmod(HOSTAPD_CONF_FILE, 0660) < 0) {
1895ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Error changing permissions of %s to 0660: %s",
19078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                HOSTAPD_CONF_FILE, strerror(errno));
19178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        unlink(HOSTAPD_CONF_FILE);
19278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        return -1;
19378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
19478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
19578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    if (chown(HOSTAPD_CONF_FILE, AID_SYSTEM, AID_WIFI) < 0) {
1965ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Error changing group ownership of %s to %d: %s",
19778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                HOSTAPD_CONF_FILE, AID_WIFI, strerror(errno));
19878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        unlink(HOSTAPD_CONF_FILE);
19978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        return -1;
20078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
20178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
20284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return ret;
2035af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt}
20431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
20578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriffvoid SoftapController::generatePsk(char *ssid, char *passphrase, char *psk_str) {
20678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    unsigned char psk[SHA256_DIGEST_LENGTH];
20778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    int j;
20878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    // Use the PKCS#5 PBKDF2 with 4096 iterations
20978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    PKCS5_PBKDF2_HMAC_SHA1(passphrase, strlen(passphrase),
21078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            reinterpret_cast<const unsigned char *>(ssid), strlen(ssid),
21178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            4096, SHA256_DIGEST_LENGTH, psk);
21278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    for (j=0; j < SHA256_DIGEST_LENGTH; j++) {
21378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        sprintf(&psk_str[j<<1], "%02x", psk[j]);
21478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    }
21578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    psk_str[j<<1] = '\0';
21678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff}
21778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
21878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
21931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt/*
22031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt * Arguments:
22131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt *	argv[2] - interface name
22231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt *	argv[3] - AP or STA
22331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt */
22431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidtint SoftapController::fwReloadSoftap(int argc, char *argv[])
22531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt{
2266665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ret, i = 0;
22731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    char *iface;
228fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt    char *fwpath;
22931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
23031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (mSock < 0) {
2315ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Softap fwrealod - failed to open socket");
23231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        return -1;
23331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
23431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (argc < 4) {
2355ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Softap fwreload - missing arguments");
23631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt        return -1;
23731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
23831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
23931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    iface = argv[2];
24031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
24131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (strcmp(argv[3], "AP") == 0) {
242fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_AP);
24354cf7fda69c3c442e7d2ac370a9c942fdb38dcd7Dmitry Shmidt    } else if (strcmp(argv[3], "P2P") == 0) {
24454cf7fda69c3c442e7d2ac370a9c942fdb38dcd7Dmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_P2P);
24531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    } else {
246fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_STA);
24731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
248fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt    if (!fwpath)
249fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt        return -1;
250389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    ret = wifi_change_fw_path((const char *)fwpath);
25131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    if (ret) {
2525ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Softap fwReload - failed: %d", ret);
25331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
25431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    else {
2557b984e3f7e724f8a3547a707210319f3d479f261Steve Block        ALOGD("Softap fwReload - Ok");
25631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    }
25731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt    return ret;
25831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt}
259666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt
260666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidtint SoftapController::clientsSoftap(char **retbuf)
261666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt{
2627e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff    /* TODO: implement over hostapd */
2637e9eb7b48345af69283afa7ca58d3be0a329931bIrfan Sheriff    return 0;
264666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt}
265