Compare commits

...

36 Commits

Author SHA1 Message Date
RenanQueiroz
ae328f2dee softap: sdk: Add 'vendor.' prefix to wlan.driver.config
* In 126af66b04,
  the prop wlan.driver.config was renamed to vendor.wlan.driver.config.
  Therefore, make the same change on softap as well.

Change-Id: I696d851c8ecd35ec42cf680149c402b3b8044cfc
2019-01-04 12:44:00 +01:00
Erfan Abdi
050bae8755 qsap: Suppress errors
Change-Id: I2809d3acd0e2ae402f9d15351bc9cb7a68f5be7a
2018-11-25 02:57:07 +02:00
Christopher N. Hesse
97cd381524 softap: sdk: Declare VNDK usage
Change-Id: I8d408c34947d9febf6afa95929bf9fb696d9d097
2018-11-25 02:57:06 +02:00
Arne Coucheron
12b534ce68 qsap: Fix missing log symbols
Add liblog to LOCAL_SHARED_LIBRARIES instead of using LOCAL_LDLIBS.

Change-Id: Iaf8fbc245babce372f047f73cb1400b19c54836d
2018-11-25 02:57:06 +02:00
Linux Build Service Account
0c179695fc Merge b44cdad94e on remote branch
Change-Id: I9c7e9422351bb2710b46c38fe782780d9223d1f8
2018-11-12 01:00:05 -08:00
Abhishek Srivastava
b44cdad94e QCSDK: Add support of wowlan_triggers, accept/deny_mac_file configuration.
This allows setting of following configs to hostapd.conf through QSAP:
wowlan_triggers accept_mac_file, deny_mac_file

CRs-Fixed: 2336537
Change-Id: If6a9e6a202e7aec86e1a3562bb392459a61287a2
2018-10-24 19:07:40 +05:30
Linux Build Service Account
4ea989bb3e Merge 996f2a81d8 on remote branch
Change-Id: I0d4923bd935dff4bb37e0903fda0461268432662
2018-10-07 22:17:33 -07:00
Ajit Vaishya
996f2a81d8 Remove reading of ini file from wlan property
Remove reading of ini file from wlan.driver.config
property since it is not used anymore.
This would prevent unnecessary avc denial warning.

CRs-Fixed: 2314284
Change-Id: Idceaef0262bada69a2d69d3bae2d69cbeff4efcf
2018-09-12 21:45:21 +05:30
Linux Build Service Account
42aa6ff408 Merge 71d1ddbe77 on remote branch
Change-Id: I67b2d54ff36bef2906e85a2a9d65ea16c3946b93
2018-09-10 02:20:10 -07:00
Srikanth Marepalli
71d1ddbe77 qsap: Add NULL check for soc & msg allocations in qsap_get_mode
Add appropriate checks to avoid NULL pointer dereferencing.

Change-Id: I9b96eeb1cf3b860416c950b5c689dc5858e194c6
CRs-Fixed: 2300013
2018-08-28 07:06:06 -07:00
Purushottam Kushwaha
68e72488ab QSAP: add support to set acs_exclude_dfs parameter.
acs_exclude_dfs is needed to avoid selection of DFS channels when
ACS (channel=0) is set for 5Ghz. This commit adds support for this
acs_exclude_dfs parameter.

Change-Id: If8a8777e7ec45bd37fd7e94e6f114852b2636b0c
CRs-Fixed: 2299524
2018-08-20 14:14:41 +05:30
Linux Build Service Account
c487e3b0fd Merge 76d63aadc7 on remote branch
Change-Id: Ie2f24a636641fed4c022ac594e186fb0c94bf4ab
2018-08-07 22:53:06 -07:00
Hu Wang
76d63aadc7 qsap: Convert SIOCGIWMODE to nl80211 for qsap_get_mode
Wireless extension is deprecated, hence convert SIOCGIWMODE to nl80211
for qsap_get_mode.

Change-Id: I30c3b4c2859b7c9c621f3f74d51e0e039837dcc9
CRs-Fixed: 2274099
2018-07-15 22:40:17 -07:00
Linux Build Service Account
babf4a5e8c Merge bfad727b06 on remote branch
Change-Id: I5941c38f9dec29f3ac8c1f3b1b56da87e5134d22
2018-06-25 03:04:11 -07:00
Veerendranath Jakkam
bfad727b06 qsap: Add NULL check for getpwnam and getgrnam.
Add appropriate checks to avoid NULL pointer dereferencing.

Change-Id: I0961a8e55fea055ee731e20ae28c833c54c32e67
CRs-Fixed: 2263188
2018-06-19 16:38:02 +05:30
Linux Build Service Account
532be76674 Merge e4263cecd2 on remote branch
Change-Id: I54be310c5ed571d51e9207b7730de869b0aee3d1
2018-06-10 22:53:25 -07:00
Purushottam Kushwaha
e4263cecd2 QSAP: Fixing LOCAL_MODULE flag to LOCAL_VENDOR_MODULE
CRs-Fixed: 2255114
Change-Id: I5d55ff31400cef3b4fcbb2ba37d373ed0de44c39
2018-06-06 14:39:35 +05:30
Purushottam Kushwaha
2ef0af2cb2 QSAP: Add support to set operating mode "any".
Currently softap sdk allows only following modes:
"b", "g", "n", "g-only", "n-only", "a".

This commit adds support for hw_mode "any" via QSAP.

CRs-Fixed: 2250379
Change-Id: I13de4c196c3cd752a902ef8bf3fed4a01f95eb6a
2018-05-31 19:06:12 +05:30
Linux Build Service Account
ec2b4ca0c0 Merge c613ebbc1c on remote branch
Change-Id: Id249c67dc0ea4fc350ce2302e81c9d5d89632d66
2018-05-28 15:01:18 -07:00
CNSS_WLAN Service
a087076b93 Merge "QSAP: Do not modify hw_mode when channel is set to 0 (for ACS)." into wlan-service.lnx.4.0 2018-05-25 07:26:54 -07:00
Purushottam Kushwaha
168beebc4e QSAP: Do not modify hw_mode when channel is set to 0 (for ACS).
Currently when channel value is less than 14, hw_mode is set to
g (or b). Application might want to run ACS by setting channel=0
in all possible hw modes.

This commit skip changing hw_mode, if channel is set to 0.

Change-Id: I0da492d70ec9c9455d79e4df33fb86a7313633ba
CRs-Fixed: 2245734
2018-05-21 07:58:24 -07:00
Purushottam Kushwaha
9283d3e375 QSAP: use vendor path for default hostapd files.
This redefines macros to use "/data/vendor/wifi/hostapd/" path for
read/write/update hostapd configuration parameters.

Additionaly, it creates libqsap_headers which other modules can use
to refer/include *.h files in this project.

Change-Id: Ice64e5a56a69882b001b2f3bcd99ba0f91ffc8a2
CRs-Fixed: 2244795
2018-05-18 20:19:42 +05:30
Veerendranath Jakkam
c613ebbc1c qsap: Fix VNDK compilation issues of libqsap.
- Removed "android_filesystem_config.h" references.
- Added cutils header library in Android.mk.
- Added required system headers explicitly.

Change-Id: I1213fc40335fba7ea52c4c296b28bc66cba72701
CRs-Fixed: 2244720
2018-05-18 18:42:03 +05:30
Veerendranath Jakkam
20f62e8554 softap: Make softap libs as vendor module libs.
- Make libqsap_sdk as vendor module.
- Remove "libQWiFiSoftApCfg" module.

Change-Id: Ie9c5795faae1d08b580cb23fe5d1a57caf1b014a
CRs-Fixed: 2239628
2018-05-06 23:35:49 +05:30
Linux Build Service Account
a3e5d4e744 Merge f4f45de50c on remote branch
Change-Id: I48f2155a7c8b7b5a03e153e77e9a739fd84bd984
2018-04-25 09:33:19 -06:00
Veerendranath Jakkam
f4f45de50c softap: Ensure VNDK compliance.
Replace LOCAL_COPY_HEADERS with LOCAL_EXPORT_C_INCLUDE_DIRS.

CRs-Fixed: 2221808
Change-Id: Ic35fef21a142b9dc76e435b3b0898e841ff76c75
2018-04-10 20:04:00 +05:30
Ajit Vaishya
3f87532c1e qsap: Support to configured Vendor IE elements in hostapd.conf.
With this commit, able to configured vendor_elements and
assocresp_elements in hostapd.conf file.
i.e
  qdc softap qccmd set vendor_elements=<Values>
  qdc softap qccmd set assocresp_elements=<Values>

Change-Id: Ib67413779a347c6567ab093bf84f87b1b63cc7db
CRs-Fixed: 2197458
2018-02-28 23:53:47 +05:30
Peng Xu
4d42a1d281 softap: Fix KW issue for array index out of bounds
Check the length of the buffer before using it calculate
the index of the data in the buffer to prevent index becoming
a negative value.

Change-Id: I3dc440dac2e4a5437e2ff70c39577876a3a97123
CRs-fixed: 2111307
2017-09-19 11:04:49 -07:00
Srinivas Dasari
a7f0080a40 qsap: Initialize setCmd to avoid uninitialized memory access
setCmd variable is used to prepare the command with the
arguments received. This can be initialized to the string "str"
to avoid possible uninitialized memory access.

Change-Id: I60cb4de5b01560e4bb079ed92e6c3bde6cfbf9c7
CRs-Fixed: 2098740
2017-09-18 12:24:26 +05:30
Abhishek Srivastava
80064989b2 qsap: Allow empty wpa_passphrase
With this commit, wpa_passphrase should follow below condition:
1. empty string (len = 0)
2. string with length >= 8 && length <= 64

Change-Id: I029ac7cc2b32b564b4e3d6b747cc584ba59e5fde
2017-09-04 04:26:38 -07:00
Ajit Vaishya
8c3357cbe4 qsap: Point the hostapd configuration location to /data/misc/wifi
1) This commit points the hostapd configuration location
   to /data/misc/wifi.
2) Aims to enable configure ctrl_interface via qsap command.

CRs-Fixed: 2091779
Change-Id: I8ebfdd4b5c359659272209ab2e0f7b92793e51c9
2017-08-14 22:47:42 +05:30
Purushottam Kushwaha
0e5ec067f7 qsap: Add API to get device mac address based on interface name.
This adds new API linux_get_ifhwaddr() which can be used to get
mac address of input interface. IOCTL SIOCGIFHWADDR is used to get
the interface address.

CRs-Fixed: 2080924
Change-Id: I1b825fb2c1f35280d2d57928be4f87d23d78decb
2017-07-27 20:49:56 -07:00
Purushottam Kushwaha
a7c3aa8a21 qsap: Modify qsapsetSoftap API to set dual2g/5g configurations.
This enhances qsapsetSoftap to take arguments for dual2g and dual5g
configurations while maintaining backward compatibility to set
config file in case of standalone sap.

Additionally enhance 'set' command to configure ssid2 and bridge
parameters which are needed for dual2g/dual5g. Also when setting
ssid2, disable ssid in config files (or vice-versa).

CRs-Fixed: 2080924
Change-Id: I60bf62e6b2ad0cde3ebdfff4814f2ab98aa24b92
2017-07-27 20:49:20 -07:00
Ajit Vaishya
a21d26579d qsap: Enhance 'set' command to configure for SAP + SAP.
This enhances existing 'set' command to allow configuration of dual
SAP. It will create/read/write/update to following configuration files:
CMD: "softap qccmd set channel=6" writes to hostapd.conf
CMD: "softap qccmd set dual2g channel=6" writes to hostapd_dual2g.conf
CMD: "softap qccmd set dual5g channel=6" writes to hostapd_dual5g.conf

Additionally enable LOG_TAG for logging APIs with TAG "QCSDK" and
modify default config file location.

CRs-Fixed: 2080924
Change-Id: I46c59de7fbd2ea273793406f0b82515df94e5c38
2017-07-27 20:48:41 -07:00
Ajit Vaishya
5d72c3af41 qsap: Add APIs to control and manage bridge interface.
This adds APIs to trigger create, delete, interface up and interface
down commands on bridge interface.
It uses following IOCTLs for sending command to linux kernel:
Add bridge iface: SIOCBRADDBR
Remove bridge iface: SIOCBRDELBR
Mark iface up/down: SIOCGIFFLAGS

CRs-Fixed: 2080924
Change-Id: I3d34dc16e9ca82dc4b550cbc83fa4120c80ad54c
2017-07-27 14:08:21 -07:00
Purushottam Kushwaha
a49496aea8 qsap: Remove support for wifi_fst from QSAP APIs
wifi_fst.h is no longer part of /hardware/libhardware_legacy/ ,
therefore, compilation of libqsap_sdk would fail. Remove dependencies
for wifi_fst from QSAP.

Additionally, skip calling 'chown' after changing configuration
parameters as QSAP is not changing ownership.

CRs-Fixed: 2069881
Change-Id: Iaadfa182270f22555e486dac24a5acafc247b943
2017-07-13 12:12:08 +05:30
7 changed files with 361 additions and 638 deletions

View File

@@ -1,20 +0,0 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_SRC_FILES := QWiFiSoftApCfg.c
LOCAL_MODULE := libQWiFiSoftApCfg
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
$(JNI_H_INCLUDE)
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_SHARED_LIBRARIES := libsysutils libcutils libnetutils libcrypto
include $(BUILD_SHARED_LIBRARY)

View File

@@ -1,410 +0,0 @@
/*
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "QWiFiSoftApCfg.h"
#define UPDATE_ERROR_CODE(msg, code) \
{ \
int rc; \
rc = snprintf(resp, sizeof(resp), "failure %s:%s",msg, code); \
if ( rc == sizeof(resp)) resp[sizeof(resp)-1] = 0; \
ALOGE("%s",resp); \
}
static struct sockaddr_nl rtnl_local;
static int rtnl_fd = -1;
static char evt_buf[MAX_EVT_BUF_SIZE];
static int evt_len;
static void softap_handle_custom_event(char * buf, int len)
{
if (strncmp(buf, "AUTO-SHUT.indication ", strlen("AUTO-SHUT.indication ")) == 0)
{
ALOGD("EVENT: Custom Event\n");
snprintf(evt_buf, sizeof(evt_buf), "105 AP Shutdown");
}
}
static void softap_handle_associated_event(char *mac_addr)
{
snprintf(evt_buf, sizeof(evt_buf), "102 Station " HWA_FORM " Associated",
HWA_ARG(mac_addr));
}
static void softap_handle_disassociated_event(char *mac_addr)
{
snprintf(evt_buf, sizeof(evt_buf), "103 Station " HWA_FORM " Disassociated",
HWA_ARG(mac_addr));
}
static void softap_handle_wireless_event(char *atr, int atrlen)
{
int len = 0;
struct iw_event iwe;
char *buffer = atr + RTA_ALIGN(RTATTRLEN);
atrlen -= RTA_ALIGN(RTATTRLEN);
while ((len + (int)IW_EV_LCP_LEN) < atrlen) {
memcpy((char *)&iwe, buffer + len, sizeof(struct iw_event));
if (iwe.len <= IW_EV_LCP_LEN)
break;
ALOGD("Received Wireless Event: cmd=0x%x len=%d", iwe.cmd, iwe.len);
switch (iwe.cmd) {
case IWEVEXPIRED:
ALOGD("EVENT: IWEVEXPIRED\n");
softap_handle_disassociated_event(iwe.u.addr.sa_data);
break;
case IWEVREGISTERED:
ALOGD("EVENT: IWEVREGISTERED\n");
softap_handle_associated_event(iwe.u.addr.sa_data);
break;
case IWEVCUSTOM:
ALOGD("EVENT: Custom Event\n");
softap_handle_custom_event(buffer + len + IW_EV_POINT_LEN, iwe.u.data.length);
break;
default:
break;
}
len += iwe.len;
}
return;
}
void softap_handle_rtm_link_event(struct nlmsghdr *hdr)
{
char *ptr = (char *)NLMSG_DATA(hdr);
struct rtattr *atr;
int atr_len;
if ((hdr->nlmsg_len - MSGHDRLEN) < IFINFOLEN) {
ALOGD("Message Length Problem1");
return;
}
if ((atr_len = hdr->nlmsg_len - NLMSG_ALIGN(IFINFOLEN)) < 0) {
ALOGD("Message Length Problem2");
return;
}
ptr += NLMSG_ALIGN(IFINFOLEN);
atr = (struct rtattr *)ptr;
while (RTA_OK(atr, atr_len)) {
switch (atr->rta_type) {
case IFLA_WIRELESS:
softap_handle_wireless_event((char *)atr,
atr->rta_len);
break;
default:
break;
}
atr = RTA_NEXT(atr, atr_len);
}
return;
}
static void softap_handle_iface_event(void)
{
int cnt, mlen = 0;
char *ptr, buffer[MAX_RECV_BUF_SIZE];
socklen_t slen;
struct nlmsghdr * hdr;
while (1) {
cnt = recvfrom(rtnl_fd, buffer, sizeof(buffer),
MSG_DONTWAIT,
(struct sockaddr *)&rtnl_local, &slen);
if (cnt <= 0) {
buffer[0] = '\0';
ALOGD("recvfrom failed");
return;
}
ptr = buffer;
while (cnt >= MSGHDRLEN) {
hdr = (struct nlmsghdr *)ptr;
mlen = hdr->nlmsg_len;
if ((mlen > cnt) || ((mlen - MSGHDRLEN) < 0)) {
break;
}
switch (hdr->nlmsg_type) {
case RTM_NEWLINK:
case RTM_DELLINK:
softap_handle_rtm_link_event(hdr);
break;
}
mlen = NLMSG_ALIGN(hdr->nlmsg_len);
cnt -= mlen;
ptr += mlen;
}
}
return;
}
static inline int softap_rtnl_wait(void)
{
fd_set fds;
int oldfd, ret;
if (rtnl_fd < 0) {
ALOGD("Netlink Socket Not Available");
return -1;
}
/* Initialize fds */
FD_ZERO(&fds);
FD_SET(rtnl_fd, &fds);
oldfd = rtnl_fd;
/* Wait for some trigger event */
ret = select(oldfd + 1, &fds, NULL, NULL, NULL);
if (ret < 0) {
/* Error Occurred */
ALOGD("Select on Netlink Socket Failed");
return ret;
} else if (!ret) {
ALOGD("Select on Netlink Socket Timed Out");
/* Timeout Occurred */
return -1;
}
/* Check if any event is available for us */
if (FD_ISSET(rtnl_fd, &fds)) {
softap_handle_iface_event();
}
return 0;
}
static void softap_rtnl_close(void)
{
close(rtnl_fd);
}
static int softap_rtnl_open(void)
{
int addr_len;
rtnl_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (rtnl_fd < 0) {
ALOGE("open netlink socket failed");
return -1;
}
memset(&rtnl_local, 0, sizeof(rtnl_local));
rtnl_local.nl_family = AF_NETLINK;
rtnl_local.nl_groups = RTMGRP_LINK;
if (bind(rtnl_fd, (struct sockaddr*)&rtnl_local,
sizeof(rtnl_local)) < 0) {
ALOGE("bind netlink socket failed");
return -1;
}
addr_len = sizeof(rtnl_local);
if (getsockname(rtnl_fd, (struct sockaddr*)&rtnl_local,
(socklen_t *) &addr_len) < 0) {
ALOGE("getsockname failed");
return -1;
}
if (addr_len != sizeof(rtnl_local)) {
ALOGE("Wrong address length %d\n", addr_len);
return -1;
}
if (rtnl_local.nl_family != AF_NETLINK) {
ALOGE("Wrong address family %d\n", rtnl_local.nl_family);
return -1;
}
return 0;
}
JNIEXPORT void JNICALL
Java_com_qualcomm_wifi_softap_QWiFiSoftApCfg_SapCloseNetlink
(JNIEnv *env, jobject obj)
{
softap_rtnl_close();
return;
}
JNIEXPORT jstring JNICALL
Java_com_qualcomm_wifi_softap_QWiFiSoftApCfg_SapWaitForEvent
(JNIEnv *env, jobject obj)
{
int ret;
do {
evt_len = 0;
memset(evt_buf, 0, sizeof(evt_buf));
ret = softap_rtnl_wait();
} while (!strlen(evt_buf));
return (*env)->NewStringUTF(env, evt_buf);
}
JNIEXPORT jboolean JNICALL
Java_com_qualcomm_wifi_softap_QWiFiSoftApCfg_SapOpenNetlink
(JNIEnv *env, jobject obj)
{
if (softap_rtnl_open() != 0) {
ALOGD("Netlink Open Fail");
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jstring JNICALL
Java_com_qualcomm_wifi_softap_QWiFiSoftApCfg_SapSendCommand
(JNIEnv *env, jobject obj, jstring jcmd)
{
const char *pcmd;
char cmd[MAX_CMD_SIZE];
char resp[MAX_RESP_SIZE];
int sock = -1;
int rc;
int done = 0;
char code[32] = {0};
int connect_retry;
strlcpy(cmd, "softap qccmd ", sizeof(cmd));
pcmd = (char *) ((*env)->GetStringUTFChars(env, jcmd, NULL));
if ( pcmd == NULL ) {
UPDATE_ERROR_CODE("Command not handled","");
goto end;
}
ALOGD("Received Command: %s\n", pcmd);
if ((strlen(cmd) + strlen(pcmd)) >= sizeof(cmd)) {
UPDATE_ERROR_CODE("Command length is larger than MAX_CMD_SIZE", "");
goto end;
}
strlcat(cmd, pcmd, sizeof(cmd));
connect_retry = 0;
while ( 1 ) {
if ((sock = socket_local_client("netd",
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM)) < 0) {
if (connect_retry > 3) {
UPDATE_ERROR_CODE("Error connecting",
strerror(errno));
goto end;
}
ALOGW("Unable to connect to netd, retrying ...\n");
sleep(1);
} else {
break;
}
connect_retry++;
}
if (write(sock, cmd, strlen(cmd) + 1) < 0) {
UPDATE_ERROR_CODE("Error Writing to socket", strerror(errno));
goto end;
}
while (!done) {
int i;
if ((rc = read(sock, resp, sizeof(resp))) <= 0) {
if (rc == 0) {
UPDATE_ERROR_CODE("Lost connection to Netd",
strerror(errno));
} else {
UPDATE_ERROR_CODE("Error reading data",
strerror(errno));
}
done = 1;
} else {
/* skip broadcase messages */
i = 0;
while(resp[i] && (i<(int)(sizeof(code)-1)) &&
(resp[i] != ' ') && (resp[i] != '\t')) {
code[i] = resp[i];
i++;
}
code[i] = '\0';
if ( (!strcmp(code, "success")) ||
(!strcmp(code, "failure")) ) {
done=1;
} else {
ALOGW("Code(%s)\n", code);
ALOGW("Ignore messages : %s\n", resp);
}
}
}
end:
(*env)->ReleaseStringUTFChars(env, jcmd, pcmd);
if( sock >= 0 ){
close(sock);
sock = -1;
}
return (*env)->NewStringUTF(env, resp);
}

View File

@@ -1,87 +0,0 @@
/*
* Copyright (c) 2010, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __QWIFISOFTAPCFG
#define __QWIFISOFTAPCFG
#define LOG_TAG "QWIFIAPCFG"
#include "jni.h"
#include <utils/Log.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/wireless.h>
#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>
typedef unsigned char u8;
#define HWA_FORM "%02X:%02X:%02X:%02X:%02X:%02X"
#define HWA_ARG(x) *(((u8 *)x + 0)), *(((u8 *)x + 1)), \
*(((u8 *)x + 2)), *(((u8 *)x + 3)), \
*(((u8 *)x + 4)), *(((u8 *)x + 5))
#define MAX_RESP_SIZE 256
#define MAX_CMD_SIZE 256
#define MAX_EVT_BUF_SIZE 256
#define MAX_RECV_BUF_SIZE 256
#define MSGHDRLEN ((int)(sizeof(struct nlmsghdr)))
#define IFINFOLEN ((int)(sizeof(struct ifinfomsg)))
#define RTATTRLEN ((int)(sizeof(struct rtattr)))
#ifndef IFLA_WIRELESS
#define IFLA_WIRELESS (IFLA_MASTER + 1)
#endif
#endif

View File

@@ -10,11 +10,16 @@ LOCAL_MODULE:= libqsap_sdk
LOCAL_MODULE_TAGS := optional LOCAL_MODULE_TAGS := optional
ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED), true)
LOCAL_VENDOR_MODULE := true
endif
LOCAL_CFLAGS += -DSDK_VERSION=\"0.0.1.0\" LOCAL_CFLAGS += -DSDK_VERSION=\"0.0.1.0\"
LOCAL_COPY_HEADERS_TO := sdk/softap/include LOCAL_USE_VNDK := true
LOCAL_COPY_HEADERS := qsap_api.h
LOCAL_COPY_HEADERS += qsap.h LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/qsap_api.h \
$(LOCAL_PATH)/qsap.h
ifdef WIFI_DRIVER_MODULE_PATH ifdef WIFI_DRIVER_MODULE_PATH
LOCAL_CFLAGS += -DWIFI_DRIVER_MODULE_PATH=\"$(WIFI_DRIVER_MODULE_PATH)\" LOCAL_CFLAGS += -DWIFI_DRIVER_MODULE_PATH=\"$(WIFI_DRIVER_MODULE_PATH)\"
@@ -56,12 +61,30 @@ ifdef WIFI_DRIVER_DEF_CONF_FILE
LOCAL_CFLAGS += -DWIFI_DRIVER_DEF_CONF_FILE=\"$(WIFI_DRIVER_DEF_CONF_FILE)\" LOCAL_CFLAGS += -DWIFI_DRIVER_DEF_CONF_FILE=\"$(WIFI_DRIVER_DEF_CONF_FILE)\"
endif endif
LOCAL_CFLAGS += \
-Wall \
-Werror \
-Wno-unused-variable \
-Wno-unused-value \
-Wno-format \
-Wno-sometimes-uninitialized \
-Wno-enum-conversion \
-Wno-unused-parameter \
-Wno-implicit-function-declaration
LOCAL_SRC_FILES := qsap_api.c \ LOCAL_SRC_FILES := qsap_api.c \
qsap.c qsap.c
LOCAL_PRELINK_MODULE := false LOCAL_PRELINK_MODULE := false
LOCAL_SHARED_LIBRARIES := libnetutils libutils libbinder libcutils libhardware_legacy libnl LOCAL_SHARED_LIBRARIES := libnetutils libutils libbinder libcutils libhardware_legacy libnl liblog
LOCAL_HEADER_LIBRARIES := libcutils_headers
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libqsap_headers
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
LOCAL_VENDOR_MODULE := true
include $(BUILD_HEADER_LIBRARY)

View File

@@ -33,6 +33,8 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <sched.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <linux/if.h> #include <linux/if.h>
@@ -46,15 +48,15 @@
#define LOG_TAG "QCLDR-" #define LOG_TAG "QCLDR-"
#include "cutils/log.h" #include <cutils/log.h>
#include "cutils/memory.h" #include <cutils/memory.h>
#include "cutils/misc.h" #include <cutils/misc.h>
#include "cutils/properties.h" #include <cutils/properties.h>
#include "private/android_filesystem_config.h" #include <grp.h>
#include <pwd.h>
#include "qsap_api.h" #include "qsap_api.h"
#include "qsap.h" #include "qsap.h"
#include "wifi_fst.h"
#include <sys/system_properties.h> #include <sys/system_properties.h>
@@ -601,6 +603,8 @@ int wigig_ensure_entropy_file_exists()
{ {
int ret; int ret;
int destfd; int destfd;
struct passwd *pw;
struct group *gr;
ret = access(WIGIG_ENTROPY_FILE, R_OK|W_OK); ret = access(WIGIG_ENTROPY_FILE, R_OK|W_OK);
if ((ret == 0) || (errno == EACCES)) { if ((ret == 0) || (errno == EACCES)) {
@@ -632,9 +636,17 @@ int wigig_ensure_entropy_file_exists()
return -1; return -1;
} }
if (chown(WIGIG_ENTROPY_FILE, AID_SYSTEM, AID_WIFI) < 0) { pw = getpwnam("system");
gr = getgrnam("wifi");
if (pw && gr) {
if (chown(WIGIG_ENTROPY_FILE, pw->pw_uid, gr->gr_gid) < 0) {
ALOGE("Error changing group ownership of %s to %d: %s", ALOGE("Error changing group ownership of %s to %d: %s",
WIGIG_ENTROPY_FILE, AID_WIFI, strerror(errno)); WIGIG_ENTROPY_FILE, gr->gr_gid, strerror(errno));
unlink(WIGIG_ENTROPY_FILE);
return -1;
}
} else {
ALOGE("Cannot get pw_uid or gr_gid : %s", strerror(errno));
unlink(WIGIG_ENTROPY_FILE); unlink(WIGIG_ENTROPY_FILE);
return -1; return -1;
} }
@@ -696,20 +708,3 @@ s32 wifi_qsap_stop_wigig_softap(void)
usleep(AP_BSS_STOP_DELAY); usleep(AP_BSS_STOP_DELAY);
return eSUCCESS; return eSUCCESS;
} }
int qsap_prepare_softap()
{
ALOGD("Starting fstman\n");
return wifi_start_fstman(TRUE);
}
int qsap_unprepare_softap()
{
ALOGD("Stopping fstman\n");
return wifi_stop_fstman(TRUE);
}
int qsap_is_fst_enabled()
{
return is_fst_enabled();
}

364
softap/sdk/qsap_api.c Executable file → Normal file
View File

@@ -43,8 +43,8 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <private/android_filesystem_config.h>
#include <net/if.h> #include <net/if.h>
#include <net/if_arp.h>
#include <netlink/netlink.h> #include <netlink/netlink.h>
#include <netlink/genl/genl.h> #include <netlink/genl/genl.h>
#include <netlink/genl/family.h> #include <netlink/genl/family.h>
@@ -64,10 +64,10 @@
#define QCSAP_PARAM_GET_AUTO_CHANNEL 9 #define QCSAP_PARAM_GET_AUTO_CHANNEL 9
#define WE_SET_SAP_CHANNELS 3 #define WE_SET_SAP_CHANNELS 3
//#define LOG_TAG "QCSDK-" #define LOG_TAG "QCSDK"
#include "cutils/properties.h" #include <cutils/properties.h>
#include "cutils/log.h" #include <cutils/log.h>
#define SKIP_BLANK_SPACE(x) {while(*x != '\0') { if((*x == ' ') || (*x == '\t')) x++; else break; }} #define SKIP_BLANK_SPACE(x) {while(*x != '\0') { if((*x == ' ') || (*x == '\t')) x++; else break; }}
@@ -84,6 +84,15 @@ s8 *Cmd_req[eCMD_REQ_LAST] = {
"set" "set"
}; };
/** Supported config file requests.
* WANRING: The enum eConf_req in the file qsap_api.h should be
* updated if Conf_req[], us updated
*/
s8 *Conf_req[CONF_REQ_LAST] = {
"dual2g",
"dual5g"
};
/* /*
* WARNING: On updating the cmd_list, the enum esap_cmd in file * WARNING: On updating the cmd_list, the enum esap_cmd in file
* qsap_api.h must be updates to reflect the changes * qsap_api.h must be updates to reflect the changes
@@ -167,6 +176,16 @@ static struct Command cmd_list[eCMD_LAST] = {
{ "ieee80211h", NULL }, { "ieee80211h", NULL },
{ "enable_wigig_softap", NULL }, { "enable_wigig_softap", NULL },
{ "interface", NULL }, { "interface", NULL },
{ "ssid2", NULL },
{ "bridge", NULL },
{ "ctrl_interface", NULL },
{ "vendor_elements", NULL },
{ "assocresp_elements", NULL },
{ "acs_exclude_dfs", NULL },
{ "wowlan_triggers", "any" },
{ "accept_mac_file", NULL },
{ "deny_mac_file", NULL },
}; };
struct Command qsap_str[eSTR_LAST] = { struct Command qsap_str[eSTR_LAST] = {
@@ -193,7 +212,7 @@ struct Command qsap_str[eSTR_LAST] = {
/** Supported operating mode */ /** Supported operating mode */
char *hw_mode[HW_MODE_UNKNOWN] = { char *hw_mode[HW_MODE_UNKNOWN] = {
"b", "g", "n", "g-only", "n-only", "a" "b", "g", "n", "g-only", "n-only", "a", "any"
}; };
/** configuration file path */ /** configuration file path */
@@ -247,6 +266,9 @@ static s32 qsap_read_cfg(s8 *pfile, struct Command * pcmd, s8 *presp, u32 *plen,
while(NULL != fgets(buf, MAX_CONF_LINE_LEN, fcfg)) { while(NULL != fgets(buf, MAX_CONF_LINE_LEN, fcfg)) {
s8 *pline = buf; s8 *pline = buf;
if (strlen(buf) == 0)
continue;
/** Skip the commented lines */ /** Skip the commented lines */
if(buf[0] == '#') { if(buf[0] == '#') {
if (ignore_comment) { if (ignore_comment) {
@@ -399,14 +421,6 @@ static s32 qsap_write_cfg(s8 *pfile, struct Command * pcmd, s8 *pVal, s8 *presp,
unlink(pfile); unlink(pfile);
return -1; return -1;
} }
if (chown(pfile, AID_SYSTEM, AID_WIFI) < 0) {
ALOGE("Error changing group ownership of %s to %d: %s",
pfile, AID_WIFI, strerror(errno));
unlink(pfile);
return -1;
}
if(result == eERR_UNKNOWN) if(result == eERR_UNKNOWN)
return eERR_FEATURE_NOT_ENABLED; return eERR_FEATURE_NOT_ENABLED;
@@ -552,14 +566,6 @@ static s32 qsap_change_cfg(s8 *pfile, struct Command * pcmd, u32 status)
unlink(pfile); unlink(pfile);
return -1; return -1;
} }
if (chown(pfile, AID_SYSTEM, AID_WIFI) < 0) {
ALOGE("Error changing group ownership of %s to %d: %s",
pfile, AID_WIFI, strerror(errno));
unlink(pfile);
return -1;
}
return 0; return 0;
} }
@@ -1303,54 +1309,105 @@ error:
} }
static int iftypeCallback(struct nl_msg* msg, void* arg)
{
struct nlmsghdr* ret_hdr = nlmsg_hdr(msg);
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
int* type = arg;
struct genlmsghdr *gnlh = (struct genlmsghdr*) nlmsg_data(ret_hdr);
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (tb_msg[NL80211_ATTR_IFTYPE]) {
*type = nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]);
}
return NL_SKIP;
}
/** /**
* Get the mode of operation. * Get the mode of operation.
*/ */
int qsap_get_mode(s32 *pmode) int qsap_get_mode(s32 *pmode)
{ {
int sock; int ret = eERR_UNKNOWN;
struct iwreq wrq; struct nl_sock* sk = NULL;
int nl80211_id = -1;
int if_type = -1;
s8 interface[MAX_CONF_LINE_LEN]; s8 interface[MAX_CONF_LINE_LEN];
u32 len = MAX_CONF_LINE_LEN; u32 len = MAX_CONF_LINE_LEN;
s8 *pif; s8 *pif;
int ret; struct nl_msg* msg = NULL;
sap_auto_channel_info sap_autochan_info;
s32 *pchan;
*pmode = -1; //get interface name
if(NULL == (pif = qsap_get_config_value(pconffile, if(NULL == (pif = qsap_get_config_value(pconffile,
&qsap_str[STR_INTERFACE], interface, &len))) { &qsap_str[STR_INTERFACE], interface, &len))) {
ALOGD("%s :interface error \n", __func__); ALOGD("%s :interface error \n", __func__);
goto error; goto nla_put_failure;
} }
interface[len] = '\0'; interface[len] = '\0';
sock = socket(AF_INET, SOCK_DGRAM, 0); //allocate socket
if(sock < 0) { sk = nl_socket_alloc();
ALOGD("%s :socket error \n", __func__);
goto error; //return if socket allocation fails
if(sk == NULL){
ALOGE( "socket allocation failure");
return ret;
} }
memset(&wrq, 0, sizeof(wrq)); //connect to generic netlink
strlcpy(wrq.ifr_name, pif, sizeof(wrq.ifr_name)); if (genl_connect(sk)) {
ALOGE( "Netlink socket Connection failure");
ret = eERR_UNKNOWN;
goto nla_put_failure;
}
ret = ioctl(sock, SIOCGIWMODE, &wrq); //find the nl80211 driver ID
nl80211_id = genl_ctrl_resolve(sk, "nl80211");
//attach a callback
nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM,
iftypeCallback, &if_type);
//allocate a message
msg = nlmsg_alloc();
//return if message allocation fails
if(msg == NULL){
ALOGE( "message allocation failure");
goto nla_put_failure;
}
// setup the message
genlmsg_put(msg, 0, 0, nl80211_id, 0, 0, NL80211_CMD_GET_INTERFACE, 0);
//add message attributes
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(pif));
// Send the message
ret = nl_send_auto_complete(sk, msg);
if (ret < 0 ) { if (ret < 0 ) {
ALOGE("%s: ioctl failure \n",__func__); ALOGE( "nl_send_auto_complete failure");
close(sock); ret = eERR_UNKNOWN;
goto error; goto nla_put_failure;
} }
*pmode = *(s32 *)(&wrq.u.mode); //block for message to return
ALOGE("%s: ioctl Get Mode = %d \n",__func__, (int)*pmode); nl_recvmsgs_default(sk);
close(sock); *pmode = if_type;
return eSUCCESS; ALOGI("%s: (%s) NL80211 Get Mode = %d \n",__func__, pif, (int)*pmode);
ret = eSUCCESS;
error: nla_put_failure:
*pmode = -1; if (sk)
ALOGE("%s: (Failure) ioctl Get Mode = %d \n",__func__, (int)*pmode); nl_socket_free(sk);
return eERR_UNKNOWN; if (msg)
nlmsg_free(msg);
return ret;
} }
/** /**
@@ -2372,6 +2429,10 @@ static int qsap_set_channel(s32 channel, s8 *tbuf, u32 *tlen)
ulen = *tlen; ulen = *tlen;
/* Do not worry about hw_mode if intention is to use ACS (channel=0) */
if (channel == 0)
goto end;
/** Read the current operating mode */ /** Read the current operating mode */
if(NULL == (pcfgval = qsap_get_config_value(pconffile, &cmd_list[eCMD_HW_MODE], tbuf, &ulen))) { if(NULL == (pcfgval = qsap_get_config_value(pconffile, &cmd_list[eCMD_HW_MODE], tbuf, &ulen))) {
return eERR_UNKNOWN; return eERR_UNKNOWN;
@@ -2408,6 +2469,7 @@ static int qsap_set_channel(s32 channel, s8 *tbuf, u32 *tlen)
} }
} }
end:
qsap_scnprintf(schan, sizeof(schan), "%ld", channel); qsap_scnprintf(schan, sizeof(schan), "%ld", channel);
return qsap_write_cfg(pcfg, &cmd_list[eCMD_CHAN], schan, tbuf, tlen, HOSTAPD_CONF_QCOM_FILE); return qsap_write_cfg(pcfg, &cmd_list[eCMD_CHAN], schan, tbuf, tlen, HOSTAPD_CONF_QCOM_FILE);
@@ -2439,7 +2501,9 @@ static int qsap_set_operating_mode(s32 mode, s8 *pmode, int pmode_len, s8 *tbuf,
qsap_change_cfg(pcfg, &cmd_list[eCMD_REQUIRE_HT],ENABLE); qsap_change_cfg(pcfg, &cmd_list[eCMD_REQUIRE_HT],ENABLE);
/* fall through */ /* fall through */
case HW_MODE_N: case HW_MODE_N:
case HW_MODE_G:
case HW_MODE_A: case HW_MODE_A:
case HW_MODE_ANY:
ulen = *tlen; ulen = *tlen;
qsap_write_cfg(pcfg, &cmd_list[eCMD_IEEE80211N],ieee11n_enable, tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE); qsap_write_cfg(pcfg, &cmd_list[eCMD_IEEE80211N],ieee11n_enable, tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE);
break; break;
@@ -2528,6 +2592,15 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
SKIP_BLANK_SPACE(pcmd); SKIP_BLANK_SPACE(pcmd);
if(!(strncmp(pcmd, Conf_req[CONF_2g], strlen(Conf_req[CONF_2g])))) {
pcmd += strlen(Conf_req[CONF_2g]);
SKIP_BLANK_SPACE(pcmd);
} else if (!(strncmp(pcmd, Conf_req[CONF_5g], strlen(Conf_req[CONF_5g])))) {
pcmd += strlen(Conf_req[CONF_5g]);
SKIP_BLANK_SPACE(pcmd);
} else {
// DO NOTHING
}
cNum = qsap_get_cmd_num(pcmd); cNum = qsap_get_cmd_num(pcmd);
if(cNum == eCMD_INVALID) { if(cNum == eCMD_INVALID) {
*plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_ARG); *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_ARG);
@@ -2537,7 +2610,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
pVal = pcmd + strlen(cmd_list[cNum].name); pVal = pcmd + strlen(cmd_list[cNum].name);
if( (cNum != eCMD_COMMIT) && if( (cNum != eCMD_COMMIT) &&
(cNum != eCMD_RESET_TO_DEFAULT) && (cNum != eCMD_RESET_TO_DEFAULT) &&
((*pVal != '=') || (strlen(pVal) < 2)) ) { ((*pVal != '=') || (((eCMD_PASSPHRASE != cNum)) && (strlen(pVal) < 2)))) {
*plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_ARG); *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_ARG);
return; return;
} }
@@ -2660,6 +2733,8 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
value = strlen(pVal); value = strlen(pVal);
if(SSD_MAX_LEN < value) if(SSD_MAX_LEN < value)
goto error; goto error;
/* Disable ssid2 while setting ssid */
qsap_change_cfg(pcfg, &cmd_list[eCMD_SSID2], DISABLE);
break; break;
case eCMD_SET_MAX_CLIENTS: case eCMD_SET_MAX_CLIENTS:
@@ -3049,6 +3124,10 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
*plen = qsap_scnprintf(presp, *plen, "%s", (value == eSUCCESS) ? SUCCESS : *plen = qsap_scnprintf(presp, *plen, "%s", (value == eSUCCESS) ? SUCCESS :
ERR_UNKNOWN); ERR_UNKNOWN);
return; return;
case eCMD_SSID2:
/* Disable ssid while setting ssid2 */
qsap_change_cfg(pcfg, &cmd_list[eCMD_SSID], DISABLE);
break;
default: ; default: ;
/** Do not goto error, in default case */ /** Do not goto error, in default case */
@@ -3088,9 +3167,17 @@ void qsap_hostd_exec_cmd(s8 *pcmd, s8 *presp, u32 *plen)
/* Skip any blank spaces */ /* Skip any blank spaces */
SKIP_BLANK_SPACE(pcmd); SKIP_BLANK_SPACE(pcmd);
if(!(strncmp(pcmd, Cmd_req[eCMD_SET], strlen(Cmd_req[eCMD_SET])))) {
if(!(strncmp(pcmd+4, Conf_req[CONF_2g], strlen(Conf_req[CONF_2g])))) {
pconffile = CONFIG_FILE_2G;
} else if (!(strncmp(pcmd+4, Conf_req[CONF_5g], strlen(Conf_req[CONF_5g])))) {
pconffile = CONFIG_FILE_5G;
} else {
pconffile = CONFIG_FILE;
}
}
check_for_configuration_files(); check_for_configuration_files();
if(fIni == NULL)
qsap_set_ini_filename();
if(!strncmp(pcmd, Cmd_req[eCMD_GET], strlen(Cmd_req[eCMD_GET])) && isblank(pcmd[strlen(Cmd_req[eCMD_GET])])) { if(!strncmp(pcmd, Cmd_req[eCMD_GET], strlen(Cmd_req[eCMD_GET])) && isblank(pcmd[strlen(Cmd_req[eCMD_GET])])) {
qsap_handle_get_request(pcmd, presp, plen); qsap_handle_get_request(pcmd, presp, plen);
@@ -3117,6 +3204,7 @@ void qsap_hostd_exec_cmd(s8 *pcmd, s8 *presp, u32 *plen)
#define DEFAULT_AUTH_ALG 1 #define DEFAULT_AUTH_ALG 1
#define RECV_BUF_LEN 255 #define RECV_BUF_LEN 255
#define CMD_BUF_LEN 255 #define CMD_BUF_LEN 255
#define SET_BUF_LEN 15
/** Command input /** Command input
argv[3] = SSID, argv[3] = SSID,
@@ -3133,6 +3221,8 @@ int qsapsetSoftap(int argc, char *argv[])
int i; int i;
int hidden = 0; int hidden = 0;
int sec = SEC_MODE_NONE; int sec = SEC_MODE_NONE;
char setCmd[SET_BUF_LEN] = "set";
int offset = 0;
ALOGD("%s, %s, %s, %d\n", __FUNCTION__, argv[0], argv[1], argc); ALOGD("%s, %s, %s, %d\n", __FUNCTION__, argv[0], argv[1], argc);
@@ -3140,22 +3230,33 @@ int qsapsetSoftap(int argc, char *argv[])
ALOGD("ARG: %d - %s\n", i+1, argv[i]); ALOGD("ARG: %d - %s\n", i+1, argv[i]);
} }
// check if 2nd arg is dual2g/dual5g
if (argc > 2 && (strncmp(argv[2], Conf_req[CONF_2g], 4) == 0)) {
snprintf(setCmd, SET_BUF_LEN, "set %s", argv[2]);
offset = 1;
argc--;
}
/* set interface */ /* set interface */
if (argc > 2) { if (argc > 2) {
snprintf(cmdbuf, CMD_BUF_LEN, "set interface=%s",argv[2]); snprintf(cmdbuf, CMD_BUF_LEN, "%s interface=%s", setCmd, argv[2 + offset]);
} }
else { else {
snprintf(cmdbuf, CMD_BUF_LEN, "set interface=%s", DEFAULT_INTFERACE); snprintf(cmdbuf, CMD_BUF_LEN, "%s interface=%s", setCmd, DEFAULT_INTFERACE);
} }
(void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen); (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
/** set SSID */ /** set SSID */
if(argc > 3) { if(argc > 3) {
qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "set ssid=%s",argv[3]); // In case of dual2g/5g, Set ssid2 with hex values to accomodate sapce and special characters.
if (offset)
qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s ssid2=%s", setCmd, argv[3 + offset]);
else
qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s ssid=%s",setCmd, argv[3]);
} }
else { else {
qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "set ssid=%s_%d", DEFAULT_SSID, rand()); qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s ssid=%s_%d", setCmd, DEFAULT_SSID, rand());
} }
(void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen); (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
@@ -3166,10 +3267,10 @@ int qsapsetSoftap(int argc, char *argv[])
rlen = RECV_BUF_LEN; rlen = RECV_BUF_LEN;
if (argc > 4) { if (argc > 4) {
if (strcmp(argv[4], "hidden") == 0) { if (strcmp(argv[4 + offset], "hidden") == 0) {
hidden = 1; hidden = 1;
} }
snprintf(cmdbuf, CMD_BUF_LEN, "set ignore_broadcast_ssid=%d", hidden); snprintf(cmdbuf, CMD_BUF_LEN, "%s ignore_broadcast_ssid=%d", setCmd, hidden);
(void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen); (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
if(strncmp("success", respbuf, rlen) != 0) { if(strncmp("success", respbuf, rlen) != 0) {
ALOGE("Failed to set ignore_broadcast_ssid \n"); ALOGE("Failed to set ignore_broadcast_ssid \n");
@@ -3179,7 +3280,7 @@ int qsapsetSoftap(int argc, char *argv[])
/** channel */ /** channel */
rlen = RECV_BUF_LEN; rlen = RECV_BUF_LEN;
if(argc > 5) { if(argc > 5) {
snprintf(cmdbuf, CMD_BUF_LEN, "set channel=%d", atoi(argv[5])); snprintf(cmdbuf, CMD_BUF_LEN, "%s channel=%d", setCmd, atoi(argv[5 + offset]));
(void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen); (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
if(strncmp("success", respbuf, rlen) != 0) { if(strncmp("success", respbuf, rlen) != 0) {
@@ -3193,22 +3294,22 @@ int qsapsetSoftap(int argc, char *argv[])
if(argc > 6) { if(argc > 6) {
/**TODO : need to identify the SEC strings for "wep", "wpa", "wpa2" */ /**TODO : need to identify the SEC strings for "wep", "wpa", "wpa2" */
if(!strcmp(argv[6], "open")) if(!strcmp(argv[6 + offset], "open"))
sec = SEC_MODE_NONE; sec = SEC_MODE_NONE;
else if(!strcmp(argv[6], "wep")) else if(!strcmp(argv[6 + offset], "wep"))
sec = SEC_MODE_WEP; sec = SEC_MODE_WEP;
else if(!strcmp(argv[6], "wpa-psk")) else if(!strcmp(argv[6 + offset], "wpa-psk"))
sec = SEC_MODE_WPA_PSK; sec = SEC_MODE_WPA_PSK;
else if(!strcmp(argv[6], "wpa2-psk")) else if(!strcmp(argv[6 + offset], "wpa2-psk"))
sec = SEC_MODE_WPA2_PSK; sec = SEC_MODE_WPA2_PSK;
qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "set security_mode=%d",sec); qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s security_mode=%d",setCmd, sec);
} }
else { else {
qsap_scnprintf(cmdbuf, sizeof(cmdbuf) , "set security_mode=%d", DEFAULT_AUTH_ALG); qsap_scnprintf(cmdbuf, sizeof(cmdbuf) , "%s security_mode=%d", setCmd, DEFAULT_AUTH_ALG);
} }
(void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen); (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
@@ -3223,11 +3324,11 @@ int qsapsetSoftap(int argc, char *argv[])
if ( (sec == SEC_MODE_WPA_PSK) || (sec == SEC_MODE_WPA2_PSK) ) { if ( (sec == SEC_MODE_WPA_PSK) || (sec == SEC_MODE_WPA2_PSK) ) {
if(argc > 7) { if(argc > 7) {
/* If the input passphrase is more than 63 characters, consider first 63 characters only*/ /* If the input passphrase is more than 63 characters, consider first 63 characters only*/
if ( strlen(argv[7]) > 63 ) argv[7][63] = '\0'; if ( strlen(argv[7 + offset]) > 63 ) argv[7 + offset][63] = '\0';
qsap_scnprintf(cmdbuf, CMD_BUF_LEN, "set wpa_passphrase=%s",argv[7]); qsap_scnprintf(cmdbuf, CMD_BUF_LEN, "%s wpa_passphrase=%s",setCmd, argv[7 + offset]);
} }
else { else {
qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "set wpa_passphrase=%s", DEFAULT_PASSPHRASE); qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s wpa_passphrase=%s", setCmd, DEFAULT_PASSPHRASE);
} }
} }
@@ -3239,7 +3340,7 @@ int qsapsetSoftap(int argc, char *argv[])
rlen = RECV_BUF_LEN; rlen = RECV_BUF_LEN;
if(argc > 8) { if(argc > 8) {
qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "set max_num_sta=%d",atoi(argv[8])); qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s max_num_sta=%d",setCmd, atoi(argv[8 + offset]));
} }
(void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen); (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
@@ -3249,7 +3350,7 @@ int qsapsetSoftap(int argc, char *argv[])
} }
rlen = RECV_BUF_LEN; rlen = RECV_BUF_LEN;
qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "set commit"); qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s commit", setCmd);
(void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen); (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
@@ -3283,14 +3384,14 @@ void check_for_configuration_files(void)
/* Check if configuration files are present, if not create the default files */ /* Check if configuration files are present, if not create the default files */
/* If configuration file does not exist copy the default file */ /* If configuration file does not exist copy the default file */
if ( NULL == (fp = fopen(CONFIG_FILE, "r")) ) { if ( NULL == (fp = fopen(pconffile, "r")) ) {
wifi_qsap_reset_to_default(CONFIG_FILE, DEFAULT_CONFIG_FILE_PATH); wifi_qsap_reset_to_default(pconffile, DEFAULT_CONFIG_FILE_PATH);
} }
else { else {
/* The configuration file could be of 0 byte size, replace with default */ /* The configuration file could be of 0 byte size, replace with default */
if (check_for_config_file_size(fp) <= 0) if (check_for_config_file_size(fp) <= 0)
wifi_qsap_reset_to_default(CONFIG_FILE, DEFAULT_CONFIG_FILE_PATH); wifi_qsap_reset_to_default(pconffile, DEFAULT_CONFIG_FILE_PATH);
fclose(fp); fclose(fp);
} }
@@ -3314,12 +3415,6 @@ void check_for_configuration_files(void)
ALOGE("Error changing permissions of %s to 0660: %s", ALOGE("Error changing permissions of %s to 0660: %s",
pfile, strerror(errno)); pfile, strerror(errno));
} }
if (chown(pfile, AID_SYSTEM, AID_WIFI) < 0) {
ALOGE("Error changing group ownership of %s to %d: %s",
pfile, AID_WIFI, strerror(errno));
}
/* If deny MAC list file does not exist, copy the default file */ /* If deny MAC list file does not exist, copy the default file */
if ( NULL == (fp = fopen(DENY_LIST_FILE, "r")) ) { if ( NULL == (fp = fopen(DENY_LIST_FILE, "r")) ) {
wifi_qsap_reset_to_default(DENY_LIST_FILE, DEFAULT_DENY_LIST_FILE_PATH); wifi_qsap_reset_to_default(DENY_LIST_FILE, DEFAULT_DENY_LIST_FILE_PATH);
@@ -3339,18 +3434,12 @@ void check_for_configuration_files(void)
ALOGE("Error changing permissions of %s to 0660: %s", ALOGE("Error changing permissions of %s to 0660: %s",
pfile, strerror(errno)); pfile, strerror(errno));
} }
if (chown(pfile, AID_SYSTEM, AID_WIFI) < 0) {
ALOGE("Error changing group ownership of %s to %d: %s",
pfile, AID_WIFI, strerror(errno));
}
return; return;
} }
void qsap_set_ini_filename(void) void qsap_set_ini_filename(void)
{ {
if (property_get("wlan.driver.config", ini_file, NULL)) { if (property_get("vendor.wlan.driver.config", ini_file, NULL)) {
fIni = ini_file; fIni = ini_file;
ALOGE("INI FILE PROP PRESENT %s\n", fIni); ALOGE("INI FILE PROP PRESENT %s\n", fIni);
} else } else
@@ -3358,6 +3447,115 @@ void qsap_set_ini_filename(void)
return; return;
} }
// IOCTL command to create and delete bridge interface //
#ifndef SIOCBRADDBR
#define SIOCBRADDBR 0x89a0
#endif
#ifndef SIOCBRDELBR
#define SIOCBRDELBR 0x89a1
#endif
static int linux_set_iface_flags(int sock, const char *ifname, int dev_up)
{
struct ifreq ifr;
int ret;
if (sock < 0)
return -1;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
ret = errno ? -errno : -999;
ALOGE("Could not read interface %s flags: %s",
ifname, strerror(errno));
return ret;
}
if (dev_up) {
if (ifr.ifr_flags & IFF_UP)
return 0;
ifr.ifr_flags |= IFF_UP;
} else {
if (!(ifr.ifr_flags & IFF_UP))
return 0;
ifr.ifr_flags &= ~IFF_UP;
}
if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
ret = errno ? -errno : -999;
ALOGE("Could not set interface %s flags (%s): %s",
ifname, dev_up ? "UP" : "DOWN", strerror(errno));
return ret;
}
return 0;
}
int qsap_control_bridge(int argc, char ** argv)
{
int br_socket;
if (argc < 4) {
ALOGE("Command not supported");
return -1;
}
br_socket = socket(PF_INET, SOCK_DGRAM, 0);
if (br_socket < 0) {
ALOGE("socket(PF_INET,SOCK_DGRAM): %s",strerror(errno));
return -1;
}
if (!strncmp(argv[2],"create", 6)) {
if (ioctl(br_socket, SIOCBRADDBR, argv[3]) < 0) {
ALOGE("Could not add bridge %s: %s", argv[3], strerror(errno));
return -1;
}
} else if (!strncmp(argv[2],"remove", 6)) {
if (ioctl(br_socket, SIOCBRDELBR, argv[3]) < 0) {
ALOGE("Could not add remove %s: %s", argv[3], strerror(errno));
return -1;
}
} else if (!strncmp(argv[2],"up", 2)) {
return linux_set_iface_flags(br_socket, argv[3], 1);
} else if (!strncmp(argv[2],"down", 4)) {
return linux_set_iface_flags(br_socket, argv[3], 0);
} else {
ALOGE("Command %s not handled.", argv[2]);
return -1;
}
return 0;
}
int linux_get_ifhwaddr(const char *ifname, char *addr)
{
struct ifreq ifr;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
#ifndef MAC2STR
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#endif
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(sock, SIOCGIFHWADDR, &ifr)) {
ALOGE("Could not get interface %s hwaddr: %s", ifname, strerror(errno));
return -1;
}
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
ALOGE("%s: Invalid HW-addr family 0x%04x", ifname, ifr.ifr_hwaddr.sa_family);
return -1;
}
memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
ALOGE("%s: " MACSTR, ifname, MAC2STR(addr));
return 0;
}
int qsap_add_or_remove_interface(const char *newIface , int createIface) int qsap_add_or_remove_interface(const char *newIface , int createIface)
{ {
const char *wlanIface = "wlan0"; const char *wlanIface = "wlan0";

36
softap/sdk/qsap_api.h Executable file → Normal file
View File

@@ -34,7 +34,7 @@
#if __cplusplus #if __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <android/log.h>
typedef unsigned char u8; typedef unsigned char u8;
typedef char s8; typedef char s8;
typedef unsigned short int u16; typedef unsigned short int u16;
@@ -88,8 +88,12 @@ enum error_val {
#define WIFI_DRIVER_DEF_CONF_FILE NULL #define WIFI_DRIVER_DEF_CONF_FILE NULL
#endif #endif
/** Configuration file name for SAP+SAP*/
#define CONFIG_FILE_2G "/data/vendor/wifi/hostapd/hostapd_dual2g.conf"
#define CONFIG_FILE_5G "/data/vendor/wifi/hostapd/hostapd_dual5g.conf"
/** Configuration file name */ /** Configuration file name */
#define CONFIG_FILE "/data/misc/wifi/hostapd.conf" #define CONFIG_FILE "/data/vendor/wifi/hostapd/hostapd.conf"
/** Default configuration file path */ /** Default configuration file path */
#define DEFAULT_CONFIG_FILE_PATH "/system/etc/hostapd/hostapd_default.conf" #define DEFAULT_CONFIG_FILE_PATH "/system/etc/hostapd/hostapd_default.conf"
@@ -98,19 +102,19 @@ enum error_val {
#define DEFAULT_ACCEPT_LIST_FILE_PATH "/system/etc/hostapd/hostapd.accept" #define DEFAULT_ACCEPT_LIST_FILE_PATH "/system/etc/hostapd/hostapd.accept"
/** Accept list file name */ /** Accept list file name */
#define ACCEPT_LIST_FILE "/data/misc/wifi/hostapd.accept" #define ACCEPT_LIST_FILE "/data/vendor/wifi/hostapd/hostapd.accept"
/** Default Deny list file name */ /** Default Deny list file name */
#define DEFAULT_DENY_LIST_FILE_PATH "/system/etc/hostapd/hostapd.deny" #define DEFAULT_DENY_LIST_FILE_PATH "/system/etc/hostapd/hostapd.deny"
/** Deny list file name */ /** Deny list file name */
#define DENY_LIST_FILE "/data/misc/wifi/hostapd.deny" #define DENY_LIST_FILE "/data/vendor/wifi/hostapd/hostapd.deny"
/** Default Ini file */ /** Default Ini file */
#define DEFAULT_INI_FILE "/persist/qcom/softap/qcom_cfg_default.ini" #define DEFAULT_INI_FILE "/persist/qcom/softap/qcom_cfg_default.ini"
/** SDK control interface path */ /** SDK control interface path */
#define SDK_CTRL_IF "/data/misc/wifi/softap_sdk_ctrl" #define SDK_CTRL_IF "/data/vendor/wifi/hostapd/ctrl/softap_sdk_ctrl"
/** Maximum length of the line in the configuration file */ /** Maximum length of the line in the configuration file */
#define MAX_CONF_LINE_LEN (156) #define MAX_CONF_LINE_LEN (156)
@@ -244,6 +248,14 @@ enum eCmd_req {
eCMD_REQ_LAST eCMD_REQ_LAST
}; };
/** config request index - in the array Conf_req[] */
enum eConf_req {
CONF_2g = 0,
CONF_5g = 1,
CONF_REQ_LAST
};
/** /**
* Command numbers, these numbers form the index into the array of * Command numbers, these numbers form the index into the array of
* command names stored in the 'cmd_list'. * command names stored in the 'cmd_list'.
@@ -333,6 +345,15 @@ typedef enum esap_cmd {
eCMD_ENABLE_WIGIG_SOFTAP = 72, eCMD_ENABLE_WIGIG_SOFTAP = 72,
eCMD_INTERFACE = 73, eCMD_INTERFACE = 73,
eCMD_SSID2 = 74,
eCMD_BRIDGE = 75,
eCMD_CTRL_INTERFACE = 76,
eCMD_VENDOR_ELEMENT = 77,
eCMD_ASSOCRESP_ELEMENT = 78,
eCMD_ACS_EXCLUDE_DFS = 79,
eCMD_WOWLAN_TRIGGERS = 80,
eCMD_ACCEPT_MAC_FILE = 81,
eCMD_DENY_MAC_FILE = 82,
eCMD_LAST /** New command numbers should be added above this */ eCMD_LAST /** New command numbers should be added above this */
} esap_cmd_t; } esap_cmd_t;
@@ -397,6 +418,7 @@ enum oper_mode {
HW_MODE_G_ONLY = 3, HW_MODE_G_ONLY = 3,
HW_MODE_N_ONLY = 4, HW_MODE_N_ONLY = 4,
HW_MODE_A = 5, HW_MODE_A = 5,
HW_MODE_ANY = 6,
HW_MODE_UNKNOWN HW_MODE_UNKNOWN
}; };
@@ -494,7 +516,7 @@ typedef struct sap_auto_channel_info {
#define IS_VALID_BSSID(x) (((value == ENABLE) || (value == DISABLE)) ? TRUE: FALSE) #define IS_VALID_BSSID(x) (((value == ENABLE) || (value == DISABLE)) ? TRUE: FALSE)
/** Validate the length of the passphrase */ /** Validate the length of the passphrase */
#define IS_VALID_PASSPHRASE_LEN(x) (((x >= PASSPHRASE_MIN) && (x <= PASSPHRASE_MAX)) ? TRUE: FALSE) #define IS_VALID_PASSPHRASE_LEN(x) ((((x >= PASSPHRASE_MIN) && (x <= PASSPHRASE_MAX)) || (x == 0)) ? TRUE: FALSE)
/** Validate the beacon interval */ /** Validate the beacon interval */
#define IS_VALID_BEACON(x) (((x >= BCN_INTERVAL_MIN) && (x <= BCN_INTERVAL_MAX)) ? TRUE: FALSE) #define IS_VALID_BEACON(x) (((x >= BCN_INTERVAL_MIN) && (x <= BCN_INTERVAL_MAX)) ? TRUE: FALSE)
@@ -603,6 +625,8 @@ int qsap_get_mode(s32 *pmode);
int qsap_prepare_softap(void); int qsap_prepare_softap(void);
int qsap_unprepare_softap(void); int qsap_unprepare_softap(void);
int qsap_is_fst_enabled(void); int qsap_is_fst_enabled(void);
int qsap_control_bridge(int argc, char ** argv);
int linux_get_ifhwaddr(const char *ifname, char *addr);
#if __cplusplus #if __cplusplus
}; // extern "C" }; // extern "C"