Compare commits

...

18 Commits

Author SHA1 Message Date
dianlujitao
ddd4779b46 qsap: Always build as vendor module
Change-Id: I529ca3951be2be0fb8d5bf93a85737b38ee8fbee
2022-08-13 20:42:10 +08:00
Dan Pasanen
c61e35d742 qsap: Add wifi_qsap_set_tx_power
Change-Id: I9ef277db6f4e068e7b92710f6039b4f261d72282
2022-08-08 17:32:28 +02:00
Nolen Johnson
9cfce3a31b qsap: Allow devices to use a local version of this
Change-Id: I7e892aaff2fc6937b3e0e4e2331006d459cbf113
2022-08-08 11:29:42 -04:00
Arne Coucheron
43f569833a qsap: Move to log/log.h
* cutils/log.h is deprecated.

Change-Id: Id29be75e58dab602ed3abcaa64571b4d565fabb3
2022-03-21 20:18:43 +01:00
Paul Keith
0a9d93707e qsap: Fix remaining compile errors
Change-Id: I65ff436ad4e02032f6fc1fd5639ce22ebf64a033
2022-03-21 13:09:26 -05:00
Nolen Johnson
b6ab59993e qsap: Compile with -Wall -Wextra -Werror
Change-Id: Ic80ea2ab7363ba57ca971eef1132f660396ddae1
2022-03-21 13:09:26 -05:00
Jeferson
630de9bda1 qsap: Resolve some compiler warnings
system/qcom/softap/sdk/qsap_api.c:351:59: error: format specifies type 'long' but the argument has type 's32' (aka 'int') [-Werror,-Wformat]
    ALOGD("cmd=%s, Val:%s, INI:%ld \n", pcmd->name, pVal, inifile);
                               ~~~                        ^~~~~~~
                               %d
system/qcom/softap/sdk/qsap_api.c:1308:58: error: format specifies type 'long' but the argument has type 's32' (aka 'int') [-Werror,-Wformat]
    ALOGD("Sap auto channel selection pautochan=%ld \n", *pautochan);
                                                ~~~      ^~~~~~~~~~
                                                %d

Change-Id: Ib6a560c94edd982156fb8b997e7891d4a406a1f4
2022-03-21 18:06:17 +01:00
RenanQueiroz
2ca7872af0 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
2022-03-13 05:02:21 +01:00
Christopher N. Hesse
8d1788b0f1 softap: sdk: Declare VNDK usage
Change-Id: I8d408c34947d9febf6afa95929bf9fb696d9d097
2022-03-02 11:15:17 -05:00
Arne Coucheron
399b3f4231 qsap: Fix missing log symbols
Add liblog to LOCAL_SHARED_LIBRARIES instead of using LOCAL_LDLIBS.

Change-Id: Iaf8fbc245babce372f047f73cb1400b19c54836d
2022-03-02 11:15:17 -05:00
Alexei Avshalom Lazar
1b6053c5cd QSAP: add support for setting EDMG configuration in hostapd
EDMG is disabled by default.
Add support for setting EDMG configuration for wigig softap.

Change-Id: I64ca5ae8dd4a837e658e07dda5a5ec6417020319
CRs-Fixed: 2567407
2019-12-01 00:52:38 -08:00
Dedy Lansky
a2dd08f8d4 QSAP: add support for setting ieee80211ax in hostapd
80211ax is enabled by default. allow disabling 80211ax for wigig
softap.
Also add support for creating a seperate config file for
wigig, to avoid conflicts with wifi APs.

Change-Id: If04f7da1695715aea037a01da11728c7350ed68c
2019-11-19 17:14:34 +02:00
Dedy Lansky
59c014ff95 QSAP: add support for HW_MODE_AD (Wigig)
Add "ad" to list of supported operating modes and add GCMP to the list
of valid pairwise ciphers.
For AD mode, disable HT capability as this is not relevant for Wigig.

Change-Id: Ia036859fe4d15b5f2fc9ff5b22c3b508fc8aae13
2019-08-08 09:58:36 +03:00
Hu Wang
62ae34e1a4 QSAP: Add support to set sae_require_mfp parameter
For SAE transtion mode, set sae_require_mfp to 1 to require MFP
for all associations using SAE.

CRs-Fixed: 2390790
Change-Id: I64bd35cbb77f6c9b64970c9a9db0a1bc3aeb2314
2019-03-21 10:33:18 -07:00
Abhishek Srivastava
2443024a1a wlan: Add default hostapd configuration file
If the hostapd configuration files are not present in /data/vendor/wifi,
copy it from the default file location /vendor/etc/hostapd
while starting softAP.

Change-Id: I3093e99cdd906d86035f9e8dbfdddb06ae9f7c80
CRs-Fixed: 2409527
2019-03-08 05:59:48 -08:00
Linux Build Service Account
e0c1c7780a Merge "QSAP: Enhance 'set' commmand to configure for OWE" 2019-01-02 18:28:14 -08:00
Hu Wang
d855500014 QSAP: Enhance 'set' commmand to configure for OWE
This creates a new hostapd_owe.conf if use below 'set' CMD:
  "softap qccmd set owe <args>"

CRs-Fixed: 2356574
Change-Id: I1ef4f11f7bdb3155dcfbc2c75fa106c8a3ecc61a
2018-12-06 18:15:48 +08:00
Hu Wang
aa4c6caf36 QSAP: Add support to set owe_transition_ifname parameter
CRs-Fixed: 2356574
Change-Id: Ib06fdc0e7120328e8cae07a4441ab23045e0c45c
2018-11-27 17:24:17 +08:00
5 changed files with 145 additions and 75 deletions

View File

@@ -1,5 +1,5 @@
ifneq ($(TARGET_USES_LOCAL_QSAP),true)
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
@@ -10,13 +10,11 @@ LOCAL_MODULE:= libqsap_sdk
LOCAL_MODULE_TAGS := optional LOCAL_MODULE_TAGS := optional
ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED), true)
LOCAL_VENDOR_MODULE := true LOCAL_VENDOR_MODULE := true
endif
LOCAL_CFLAGS += -DSDK_VERSION=\"0.0.1.0\" LOCAL_CFLAGS += -DSDK_VERSION=\"0.0.1.0\"
LOCAL_LDLIBS := -llog LOCAL_USE_VNDK := true
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/qsap_api.h \ LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/qsap_api.h \
$(LOCAL_PATH)/qsap.h $(LOCAL_PATH)/qsap.h
@@ -61,12 +59,14 @@ 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 -Wextra -Werror
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 LOCAL_HEADER_LIBRARIES := libcutils_headers
@@ -77,3 +77,4 @@ LOCAL_MODULE := libqsap_headers
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
LOCAL_VENDOR_MODULE := true LOCAL_VENDOR_MODULE := true
include $(BUILD_HEADER_LIBRARY) include $(BUILD_HEADER_LIBRARY)
endif

View File

@@ -48,7 +48,7 @@
#define LOG_TAG "QCLDR-" #define LOG_TAG "QCLDR-"
#include <cutils/log.h> #include <log/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>
@@ -196,9 +196,7 @@ static const char DRIVER_CFG80211_MODULE_ARG[] = WIFI_CFG80211_DRIVER_MODULE_A
s32 wifi_qsap_load_driver(void) s32 wifi_qsap_load_driver(void)
{ {
s32 size;
s32 ret = -1; s32 ret = -1;
s32 retry;
if (system(SDIO_POLLING_ON)) { if (system(SDIO_POLLING_ON)) {
@@ -293,7 +291,6 @@ s32 qsap_send_init_ap(void)
int s, ret; int s, ret;
struct iwreq wrq; struct iwreq wrq;
s32 status = eSUCCESS; s32 status = eSUCCESS;
u32 *params = (u32 *)&wrq.u;
/* Equivalent to: iwpriv wlan0 initAP */ /* Equivalent to: iwpriv wlan0 initAP */
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { if ((s = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
@@ -321,7 +318,6 @@ s32 qsap_send_exit_ap(void)
int s, ret; int s, ret;
struct iwreq wrq; struct iwreq wrq;
s32 status = eSUCCESS; s32 status = eSUCCESS;
u32 *params = (u32 *)&wrq.u;
/* Equivalent to: iwpriv wlan0 exitAP */ /* Equivalent to: iwpriv wlan0 exitAP */
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { if ((s = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
@@ -391,7 +387,6 @@ s32 wifi_qsap_stop_bss(void)
s8 *iface; s8 *iface;
s32 len = 128; s32 len = 128;
struct iwreq wrq; struct iwreq wrq;
struct iw_priv_args *priv_ptr;
if(ENABLE != is_softap_enabled()) { if(ENABLE != is_softap_enabled()) {
ret = eERR_BSS_NOT_STARTED; ret = eERR_BSS_NOT_STARTED;
@@ -423,7 +418,7 @@ s32 wifi_qsap_stop_bss(void)
close(sock); close(sock);
if (ret) { if (ret) {
ALOGE("IOCTL stopbss failed: %ld", ret); ALOGE("IOCTL stopbss failed: %d", ret);
ret = eERR_STOP_BSS; ret = eERR_STOP_BSS;
} else { } else {
ALOGD("STOP BSS ISSUED"); ALOGD("STOP BSS ISSUED");
@@ -483,7 +478,6 @@ s32 commit(void)
s32 wifi_qsap_start_softap() s32 wifi_qsap_start_softap()
{ {
s32 retry = 4; s32 retry = 4;
FILE * fp;
ALOGD("Starting Soft AP...\n"); ALOGD("Starting Soft AP...\n");
@@ -708,3 +702,45 @@ s32 wifi_qsap_stop_wigig_softap(void)
usleep(AP_BSS_STOP_DELAY); usleep(AP_BSS_STOP_DELAY);
return eSUCCESS; return eSUCCESS;
} }
s32 wifi_qsap_set_tx_power(s32 tx_power)
{
#define QCSAP_IOCTL_SET_MAX_TX_POWER (SIOCIWFIRSTPRIV + 22)
s32 sock;
s32 ret = eERR_SET_TX_POWER;
s8 interface[128];
s8 *iface;
s32 len = 128;
struct iwreq wrq;
if(NULL == (iface = qsap_get_config_value(CONFIG_FILE, &qsap_str[STR_INTERFACE], interface, (u32*)&len))) {
ALOGE("%s :interface error \n", __func__);
return ret;
}
/* Issue QCSAP_IOCTL_SET_MAX_TX_POWER ioctl */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
ALOGE("%s :socket error \n", __func__);
return eERR_SET_TX_POWER;
}
strlcpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name));
wrq.u.data.length = sizeof(s32);
wrq.u.data.pointer = &tx_power;
wrq.u.data.flags = 0;
ret = ioctl(sock, QCSAP_IOCTL_SET_MAX_TX_POWER, &wrq);
close(sock);
if (ret) {
ALOGE("%s :IOCTL set tx power failed: %d\n", __func__, ret);
ret = eERR_SET_TX_POWER;
} else {
ALOGD("%s :IOCTL set tx power issued\n", __func__);
ret = eSUCCESS;
}
return ret;
}

View File

@@ -48,6 +48,7 @@ s32 wifi_qsap_start_wigig_softap(void);
s32 wifi_qsap_stop_wigig_softap(void); s32 wifi_qsap_stop_wigig_softap(void);
s32 wifi_qsap_reload_softap(void); s32 wifi_qsap_reload_softap(void);
s32 wifi_qsap_unload_wifi_sta_driver(void); s32 wifi_qsap_unload_wifi_sta_driver(void);
s32 wifi_qsap_set_tx_power(s32 tx_power);
#ifdef QCOM_WLAN_CONCURRENCY #ifdef QCOM_WLAN_CONCURRENCY
s32 wifi_qsap_start_softap_in_concurrency(void); s32 wifi_qsap_start_softap_in_concurrency(void);

View File

@@ -67,10 +67,12 @@
#define LOG_TAG "QCSDK" #define LOG_TAG "QCSDK"
#include <cutils/properties.h> #include <cutils/properties.h>
#include <cutils/log.h> #include <log/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; }}
#define UNUSED __attribute__ ((unused))
/** If this variable is enabled, the soft AP is reloaded, after the commit /** If this variable is enabled, the soft AP is reloaded, after the commit
* command is received */ * command is received */
static volatile int gIniUpdated = 0; static volatile int gIniUpdated = 0;
@@ -90,7 +92,9 @@ s8 *Cmd_req[eCMD_REQ_LAST] = {
*/ */
s8 *Conf_req[CONF_REQ_LAST] = { s8 *Conf_req[CONF_REQ_LAST] = {
"dual2g", "dual2g",
"dual5g" "dual5g",
"owe",
"60g",
}; };
/* /*
@@ -185,6 +189,11 @@ static struct Command cmd_list[eCMD_LAST] = {
{ "wowlan_triggers", "any" }, { "wowlan_triggers", "any" },
{ "accept_mac_file", NULL }, { "accept_mac_file", NULL },
{ "deny_mac_file", NULL }, { "deny_mac_file", NULL },
{ "owe_transition_ifname", NULL },
{ "sae_require_mfp", NULL },
{ "ieee80211ax", NULL },
{ "enable_edmg", NULL },
{ "edmg_channel", NULL },
}; };
@@ -212,7 +221,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", "any" "b", "g", "n", "g-only", "n-only", "a", "any", "ad"
}; };
/** configuration file path */ /** configuration file path */
@@ -341,7 +350,7 @@ static s32 qsap_write_cfg(s8 *pfile, struct Command * pcmd, s8 *pVal, s8 *presp,
s8 buf[MAX_CONF_LINE_LEN+1]; s8 buf[MAX_CONF_LINE_LEN+1];
s16 len, result = FALSE; s16 len, result = FALSE;
ALOGD("cmd=%s, Val:%s, INI:%ld \n", pcmd->name, pVal, inifile); ALOGD("cmd=%s, Val:%s, INI:%d \n", pcmd->name, pVal, inifile);
/** Open the configuration file */ /** Open the configuration file */
fcfg = fopen(pfile, "r"); fcfg = fopen(pfile, "r");
@@ -615,7 +624,7 @@ static void qsap_set_security_mode(s8 *pfile, u32 sec_mode, s8 *presp, u32 *plen
} }
else { else {
/** WPA, WPA2 and mixed-mode security */ /** WPA, WPA2 and mixed-mode security */
u16 wpa_val; u16 wpa_val = 0;
u32 tmp = *plen; u32 tmp = *plen;
wep = DISABLE; wep = DISABLE;
@@ -1030,7 +1039,7 @@ static void qsap_get_mac_list(s8 *fconfile, esap_cmd_t cNum, s8 *presp, u32 *ple
FILE *fp; FILE *fp;
u32 len_remain; u32 len_remain;
s8 *pfile, *pOut; s8 *pfile, *pOut;
esap_cmd_t sNum; esap_str_t sNum;
int cnt = 0; int cnt = 0;
/** Identify the allow or deny file */ /** Identify the allow or deny file */
@@ -1184,7 +1193,7 @@ static void qsap_read_wps_state(s8 *presp, u32 *plen)
status = (atoi(pstate) == WPS_STATE_ENABLE) ? ENABLE : DISABLE; status = (atoi(pstate) == WPS_STATE_ENABLE) ? ENABLE : DISABLE;
} }
*plen = qsap_scnprintf(presp, *plen, "success %s=%ld", cmd_list[eCMD_WPS_STATE].name, status); *plen = qsap_scnprintf(presp, *plen, "success %s=%d", cmd_list[eCMD_WPS_STATE].name, status);
return; return;
} }
@@ -1234,7 +1243,7 @@ int qsap_get_operating_channel(s32 *pchan)
ALOGE("Recv len :%d \n", wrq.u.data.length); ALOGE("Recv len :%d \n", wrq.u.data.length);
*pchan = *(int *)(&wrq.u.name[0]); *pchan = *(int *)(&wrq.u.name[0]);
ALOGE("Operating channel :%ld \n", *pchan); ALOGE("Operating channel :%d \n", *pchan);
close(sock); close(sock);
return eSUCCESS; return eSUCCESS;
@@ -1256,7 +1265,6 @@ int qsap_get_sap_auto_channel_selection(s32 *pautochan)
s8 *pif; s8 *pif;
int ret; int ret;
sap_auto_channel_info sap_autochan_info; sap_auto_channel_info sap_autochan_info;
s32 *pchan;
if(ENABLE != is_softap_enabled()) { if(ENABLE != is_softap_enabled()) {
ALOGE("%s :is_softap_enabled() goto error \n", __func__); ALOGE("%s :is_softap_enabled() goto error \n", __func__);
@@ -1298,7 +1306,7 @@ int qsap_get_sap_auto_channel_selection(s32 *pautochan)
ALOGD("Recv len :%d \n", wrq.u.data.length); ALOGD("Recv len :%d \n", wrq.u.data.length);
*pautochan = *(int *)(&wrq.u.name[0]); *pautochan = *(int *)(&wrq.u.name[0]);
ALOGD("Sap auto channel selection pautochan=%ld \n", *pautochan); ALOGD("Sap auto channel selection pautochan=%d \n", *pautochan);
close(sock); close(sock);
return eSUCCESS; return eSUCCESS;
@@ -1421,7 +1429,7 @@ int qsap_set_channel_range(s8 *buf)
u32 len = MAX_CONF_LINE_LEN; u32 len = MAX_CONF_LINE_LEN;
s8 *pif; s8 *pif;
s8 *temp; s8 *temp;
int ret, i; int ret;
sap_channel_info sap_chan_range; sap_channel_info sap_chan_range;
sta_channel_info sta_chan_range; sta_channel_info sta_chan_range;
@@ -1499,9 +1507,8 @@ error:
return eERR_SET_CHAN_RANGE; return eERR_SET_CHAN_RANGE;
} }
int qsap_read_channel(s8 *pfile, struct Command *pcmd, s8 *presp, u32 *plen, s8 *pvar) int qsap_read_channel(UNUSED s8 *pfile, struct Command *pcmd, s8 *presp, u32 *plen, UNUSED s8 *pvar)
{ {
s8 *pval;
s32 chan; s32 chan;
u32 len = *plen; u32 len = *plen;
@@ -1515,12 +1522,10 @@ int qsap_read_channel(s8 *pfile, struct Command *pcmd, s8 *presp, u32 *plen, s8
return eSUCCESS; return eSUCCESS;
} }
int qsap_read_auto_channel(struct Command *pcmd, s8 *presp, u32 *plen) int qsap_read_auto_channel(UNUSED struct Command *pcmd, s8 *presp, u32 *plen)
{ {
s8 *pval, *pautoval;
s32 pautochan; s32 pautochan;
u32 len = *plen; u32 len = *plen;
int autochan;
ALOGE("%s :\n", __func__); ALOGE("%s :\n", __func__);
@@ -1550,7 +1555,7 @@ static int qsap_mac_to_macstr(s8 *pmac, u32 slen, s8 *pmstr, u32 *plen)
} }
if(totlen > 0) { if(totlen > 0) {
*pmstr--; pmstr--;
totlen--; totlen--;
} }
*pmstr = '\0'; *pmstr = '\0';
@@ -1655,7 +1660,7 @@ static void qsap_read_wep_key(s8 *pfile, struct Command *pcmd, s8 *presp, u32 *p
pkey++; pkey++;
pwep++; pwep++;
} }
*pkey--; pkey--;
*pkey = '\0'; *pkey = '\0';
*plen -= 2; *plen -= 2;
} }
@@ -1670,8 +1675,7 @@ void qsap_read_ap_stats(s8 *presp, u32 *plen)
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;
s8 *pbuf, *pout; s8 *pbuf;
u32 tlen;
if(ENABLE != is_softap_enabled()) { if(ENABLE != is_softap_enabled()) {
*plen = qsap_scnprintf(presp, *plen, "%s", ERR_SOFTAP_NOT_STARTED); *plen = qsap_scnprintf(presp, *plen, "%s", ERR_SOFTAP_NOT_STARTED);
@@ -1738,7 +1742,7 @@ void qsap_read_autoshutoff(s8 *presp, u32 *plen)
time = time / 60; /** Convert seconds to minutes */ time = time / 60; /** Convert seconds to minutes */
} }
*plen = qsap_scnprintf(presp, *plen, "success %s=%ld", cmd_list[eCMD_AP_AUTOSHUTOFF].name, time); *plen = qsap_scnprintf(presp, *plen, "success %s=%d", cmd_list[eCMD_AP_AUTOSHUTOFF].name, time);
return; return;
} }
@@ -1763,7 +1767,6 @@ static void qsap_get_from_config(esap_cmd_t cNum, s8 *presp, u32 *plen)
{ {
u32 len; u32 len;
int status; int status;
s8 * pval;
switch(cNum) { switch(cNum) {
case eCMD_ENABLE_SOFTAP: case eCMD_ENABLE_SOFTAP:
@@ -1916,6 +1919,7 @@ static esap_cmd_t qsap_get_cmd_num(s8 *cName)
for(i=0; i<eCMD_LAST; i++) { for(i=0; i<eCMD_LAST; i++) {
len = strlen(cmd_list[i].name); len = strlen(cmd_list[i].name);
if(!strncmp(cmd_list[i].name, cName, len)) { if(!strncmp(cmd_list[i].name, cName, len)) {
if((cName[len] == '=') || (cName[len] == '\0')) if((cName[len] == '=') || (cName[len] == '\0'))
return i; return i;
@@ -2470,7 +2474,7 @@ static int qsap_set_channel(s32 channel, s8 *tbuf, u32 *tlen)
} }
end: end:
qsap_scnprintf(schan, sizeof(schan), "%ld", channel); qsap_scnprintf(schan, sizeof(schan), "%d", 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);
} }
@@ -2478,11 +2482,7 @@ end:
static int qsap_set_operating_mode(s32 mode, s8 *pmode, int pmode_len, s8 *tbuf, u32 *tlen) static int qsap_set_operating_mode(s32 mode, s8 *pmode, int pmode_len, s8 *tbuf, u32 *tlen)
{ {
u32 ulen; u32 ulen;
s8 *pcfgval;
s32 channel;
s8 sconf[MAX_INT_STR+1];
s8 *pcfg = pconffile; s8 *pcfg = pconffile;
s32 rate_idx;
s8 ieee11n_enable[] = "1"; s8 ieee11n_enable[] = "1";
s8 ieee11n_disable[] = "0"; s8 ieee11n_disable[] = "0";
@@ -2511,6 +2511,10 @@ static int qsap_set_operating_mode(s32 mode, s8 *pmode, int pmode_len, s8 *tbuf,
ulen = *tlen; ulen = *tlen;
qsap_write_cfg(pcfg, &cmd_list[eCMD_IEEE80211N],ieee11n_disable, tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE); qsap_write_cfg(pcfg, &cmd_list[eCMD_IEEE80211N],ieee11n_disable, tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE);
break; break;
case HW_MODE_AD:
/** For 802.11ad, disable the 802.11 HT */
qsap_change_cfg(pcfg, &cmd_list[eCMD_HT_CAPAB], DISABLE);
break;
} }
if(mode == HW_MODE_G_ONLY || mode == HW_MODE_N_ONLY || mode == HW_MODE_N ) { if(mode == HW_MODE_G_ONLY || mode == HW_MODE_N_ONLY || mode == HW_MODE_N ) {
qsap_scnprintf(pmode, pmode_len, "%s",hw_mode[HW_MODE_G]); qsap_scnprintf(pmode, pmode_len, "%s",hw_mode[HW_MODE_G]);
@@ -2545,7 +2549,7 @@ static int qsap_set_data_rate(s32 drate_idx, s8 *presp, u32 *plen)
goto end; goto end;
} }
qsap_scnprintf(sconf, sizeof(sconf), "%ld", drate_idx); qsap_scnprintf(sconf, sizeof(sconf), "%d", drate_idx);
/** Update the rate index in the configuration */ /** Update the rate index in the configuration */
return qsap_write_cfg(fIni, &qsap_str[STR_DATA_RATE_IN_INI], sconf, presp, plen, INI_CONF_FILE); return qsap_write_cfg(fIni, &qsap_str[STR_DATA_RATE_IN_INI], sconf, presp, plen, INI_CONF_FILE);
@@ -2598,6 +2602,12 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
} else if (!(strncmp(pcmd, Conf_req[CONF_5g], strlen(Conf_req[CONF_5g])))) { } else if (!(strncmp(pcmd, Conf_req[CONF_5g], strlen(Conf_req[CONF_5g])))) {
pcmd += strlen(Conf_req[CONF_5g]); pcmd += strlen(Conf_req[CONF_5g]);
SKIP_BLANK_SPACE(pcmd); SKIP_BLANK_SPACE(pcmd);
} else if (!(strncmp(pcmd, Conf_req[CONF_owe], strlen(Conf_req[CONF_owe])))) {
pcmd += strlen(Conf_req[CONF_owe]);
SKIP_BLANK_SPACE(pcmd);
} else if (!(strncmp(pcmd, Conf_req[CONF_60g], strlen(Conf_req[CONF_60g])))) {
pcmd += strlen(Conf_req[CONF_60g]);
SKIP_BLANK_SPACE(pcmd);
} else { } else {
// DO NOTHING // DO NOTHING
} }
@@ -2644,7 +2654,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
/** Write back the integer value. This is to avoid values like 01, 001, 0001 /** Write back the integer value. This is to avoid values like 01, 001, 0001
* being written to the configuration. * being written to the configuration.
*/ */
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
qsap_set_security_mode(pconffile, value, presp, plen); qsap_set_security_mode(pconffile, value, presp, plen);
return; return;
@@ -2656,7 +2666,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
/** Write back the integer value. This is to avoid values like 01, 001, 0001 /** Write back the integer value. This is to avoid values like 01, 001, 0001
* being written to the configuration * being written to the configuration
*/ */
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
if(ACL_ALLOW_LIST == value) { if(ACL_ALLOW_LIST == value) {
value = ENABLE; value = ENABLE;
@@ -2747,7 +2757,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
/** Write back the integer value. This is to avoid values like 01, 001, 0001 /** Write back the integer value. This is to avoid values like 01, 001, 0001
* being written to the configuration * being written to the configuration
*/ */
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
break; break;
case eCMD_PASSPHRASE: case eCMD_PASSPHRASE:
value = strlen(pVal); value = strlen(pVal);
@@ -2771,7 +2781,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
/** Write back the integer value. This is to avoid values like 01, 001, 0001 /** Write back the integer value. This is to avoid values like 01, 001, 0001
* being written to the configuration * being written to the configuration
*/ */
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
break; break;
case eCMD_DTIM_PERIOD: case eCMD_DTIM_PERIOD:
@@ -2781,7 +2791,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
/** Write back the integer value. This is to avoid values like 01, 001, 0001 /** Write back the integer value. This is to avoid values like 01, 001, 0001
* being written to the configuration * being written to the configuration
*/ */
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
break; break;
case eCMD_HW_MODE: case eCMD_HW_MODE:
@@ -2810,7 +2820,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
/** Write back the integer value. This is to avoid values like 01, 001, 0001 /** Write back the integer value. This is to avoid values like 01, 001, 0001
* being written to the configuration * being written to the configuration
*/ */
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
break; break;
case eCMD_DEFAULT_KEY: case eCMD_DEFAULT_KEY:
@@ -2820,7 +2830,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
/** Write back the integer value. This is to avoid values like 01, 001, 0001 /** Write back the integer value. This is to avoid values like 01, 001, 0001
* being written to the configuration * being written to the configuration
*/ */
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
qsap_write_cfg(pcfg, &cmd_list[cNum], pVal, presp, plen, ini); qsap_write_cfg(pcfg, &cmd_list[cNum], pVal, presp, plen, ini);
@@ -2875,7 +2885,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
case eCMD_RESET_AP: case eCMD_RESET_AP:
value = atoi(pVal); value = atoi(pVal);
ALOGE("Reset :%ld \n", value); ALOGE("Reset :%d \n", value);
if(SAP_RESET_BSS == value) { if(SAP_RESET_BSS == value) {
status = wifi_qsap_stop_softap(); status = wifi_qsap_stop_softap();
if(status == eSUCCESS) { if(status == eSUCCESS) {
@@ -3001,7 +3011,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
if(TRUE != IS_VALID_WMM_STATE(value)) if(TRUE != IS_VALID_WMM_STATE(value))
goto error; goto error;
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
break; break;
case eCMD_WPS_STATE: case eCMD_WPS_STATE:
value = atoi(pVal); value = atoi(pVal);
@@ -3010,7 +3020,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
/** Write back the integer value. This is to avoid values like 01, 001, 0001 /** Write back the integer value. This is to avoid values like 01, 001, 0001
* being written to the configuration * being written to the configuration
*/ */
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
qsap_update_wps_config(pVal, presp, plen); qsap_update_wps_config(pVal, presp, plen);
return; return;
@@ -3022,8 +3032,8 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
value = atoi(pVal); value = atoi(pVal);
if(TRUE != IS_VALID_PROTECTION(value)) if(TRUE != IS_VALID_PROTECTION(value))
goto error; goto error;
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
cNum = STR_PROT_FLAG_IN_INI; sNum = STR_PROT_FLAG_IN_INI;
ini = INI_CONF_FILE; ini = INI_CONF_FILE;
break; break;
@@ -3031,7 +3041,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
value = atoi(pVal); value = atoi(pVal);
if(TRUE != IS_VALID_FRAG_THRESHOLD(value)) if(TRUE != IS_VALID_FRAG_THRESHOLD(value))
goto error; goto error;
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
break; break;
case eCMD_REGULATORY_DOMAIN: case eCMD_REGULATORY_DOMAIN:
@@ -3040,14 +3050,14 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
if(TRUE != IS_VALID_802DOT11D_STATE(value)) if(TRUE != IS_VALID_802DOT11D_STATE(value))
goto error; goto error;
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
break; break;
case eCMD_RTS_THRESHOLD: case eCMD_RTS_THRESHOLD:
value = atoi(pVal); value = atoi(pVal);
if(TRUE != IS_VALID_RTS_THRESHOLD(value)) if(TRUE != IS_VALID_RTS_THRESHOLD(value))
goto error; goto error;
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
break; break;
case eCMD_GTK_TIMEOUT: case eCMD_GTK_TIMEOUT:
@@ -3061,8 +3071,8 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
value = atoi(pVal); value = atoi(pVal);
if(TRUE != IS_VALID_TX_POWER(value)) if(TRUE != IS_VALID_TX_POWER(value))
goto error; goto error;
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
cNum = STR_TX_POWER_IN_INI; sNum = STR_TX_POWER_IN_INI;
ini = INI_CONF_FILE; ini = INI_CONF_FILE;
break; break;
@@ -3095,8 +3105,8 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
goto error; goto error;
/* copy a larger value back to pVal. Please pay special care /* copy a larger value back to pVal. Please pay special care
* in caller to make sure that the buffer has sufficient size. */ * in caller to make sure that the buffer has sufficient size. */
qsap_scnprintf(pVal, MAX_INT_STR, "%ld", value*60); qsap_scnprintf(pVal, MAX_INT_STR, "%d", value*60);
cNum = STR_AP_AUTOSHUTOFF; sNum = STR_AP_AUTOSHUTOFF;
ini = INI_CONF_FILE; ini = INI_CONF_FILE;
break; break;
@@ -3105,8 +3115,8 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
if(TRUE != IS_VALID_ENERGY_DETECT_TH(value)) if(TRUE != IS_VALID_ENERGY_DETECT_TH(value))
goto error; goto error;
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
cNum = STR_AP_ENERGY_DETECT_TH; sNum = STR_AP_ENERGY_DETECT_TH;
ini = INI_CONF_FILE; ini = INI_CONF_FILE;
break; break;
@@ -3115,7 +3125,7 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
if(TRUE != IS_VALID_DFS_STATE(value)) if(TRUE != IS_VALID_DFS_STATE(value))
goto error; goto error;
qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value); qsap_scnprintf(pVal, strlen(pVal)+1, "%d", value);
break; break;
case eCMD_SET_CHANNEL_RANGE: case eCMD_SET_CHANNEL_RANGE:
@@ -3134,8 +3144,8 @@ static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
} }
if(ini == INI_CONF_FILE) { if(ini == INI_CONF_FILE) {
ALOGD("WRITE TO INI FILE :%s\n", qsap_str[cNum].name); ALOGD("WRITE TO INI FILE :%s\n", qsap_str[sNum].name);
qsap_write_cfg(fIni, &qsap_str[cNum], pVal, presp, plen, ini); qsap_write_cfg(fIni, &qsap_str[sNum], pVal, presp, plen, ini);
} }
else { else {
qsap_write_cfg(pcfg, &cmd_list[cNum], pVal, presp, plen, ini); qsap_write_cfg(pcfg, &cmd_list[cNum], pVal, presp, plen, ini);
@@ -3163,7 +3173,7 @@ error:
*/ */
void qsap_hostd_exec_cmd(s8 *pcmd, s8 *presp, u32 *plen) void qsap_hostd_exec_cmd(s8 *pcmd, s8 *presp, u32 *plen)
{ {
ALOGD("CMD INPUT [%s][%lu]\n", pcmd, *plen); ALOGD("CMD INPUT [%s][%u]\n", pcmd, *plen);
/* Skip any blank spaces */ /* Skip any blank spaces */
SKIP_BLANK_SPACE(pcmd); SKIP_BLANK_SPACE(pcmd);
@@ -3172,6 +3182,10 @@ void qsap_hostd_exec_cmd(s8 *pcmd, s8 *presp, u32 *plen)
pconffile = CONFIG_FILE_2G; pconffile = CONFIG_FILE_2G;
} else if (!(strncmp(pcmd+4, Conf_req[CONF_5g], strlen(Conf_req[CONF_5g])))) { } else if (!(strncmp(pcmd+4, Conf_req[CONF_5g], strlen(Conf_req[CONF_5g])))) {
pconffile = CONFIG_FILE_5G; pconffile = CONFIG_FILE_5G;
} else if (!(strncmp(pcmd+4, Conf_req[CONF_owe], strlen(Conf_req[CONF_owe])))) {
pconffile = CONFIG_FILE_OWE;
} else if (!(strncmp(pcmd+4, Conf_req[CONF_60g], strlen(Conf_req[CONF_60g])))) {
pconffile = CONFIG_FILE_60G;
} else { } else {
pconffile = CONFIG_FILE; pconffile = CONFIG_FILE;
} }
@@ -3191,7 +3205,7 @@ void qsap_hostd_exec_cmd(s8 *pcmd, s8 *presp, u32 *plen)
*plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALIDREQ); *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALIDREQ);
} }
ALOGD("CMD OUTPUT [%s]\nlen :%lu\n\n", presp, *plen); ALOGD("CMD OUTPUT [%s]\nlen :%u\n\n", presp, *plen);
return; return;
} }
@@ -3230,8 +3244,11 @@ 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 // check if 2nd arg is dual2g/dual5g/owe/60g
if (argc > 2 && (strncmp(argv[2], Conf_req[CONF_2g], 4) == 0)) { if (argc > 2
&& (strncmp(argv[2], Conf_req[CONF_2g], 4) == 0
|| strncmp(argv[2], Conf_req[CONF_owe], 3) == 0
|| strncmp(argv[2], Conf_req[CONF_60g], 3) == 0)) {
snprintf(setCmd, SET_BUF_LEN, "set %s", argv[2]); snprintf(setCmd, SET_BUF_LEN, "set %s", argv[2]);
offset = 1; offset = 1;
argc--; argc--;
@@ -3439,7 +3456,7 @@ void check_for_configuration_files(void)
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

View File

@@ -77,7 +77,8 @@ enum error_val {
eERR_LOAD_FAILED_SDIOIF, eERR_LOAD_FAILED_SDIOIF,
eERR_LOAD_FAILED_SOFTAP, eERR_LOAD_FAILED_SOFTAP,
eERR_SET_CHAN_RANGE, eERR_SET_CHAN_RANGE,
eERR_GET_AUTO_CHAN eERR_GET_AUTO_CHAN,
eERR_SET_TX_POWER
}; };
#ifndef WIFI_DRIVER_CONF_FILE #ifndef WIFI_DRIVER_CONF_FILE
@@ -91,21 +92,25 @@ enum error_val {
/** Configuration file name for SAP+SAP*/ /** Configuration file name for SAP+SAP*/
#define CONFIG_FILE_2G "/data/vendor/wifi/hostapd/hostapd_dual2g.conf" #define CONFIG_FILE_2G "/data/vendor/wifi/hostapd/hostapd_dual2g.conf"
#define CONFIG_FILE_5G "/data/vendor/wifi/hostapd/hostapd_dual5g.conf" #define CONFIG_FILE_5G "/data/vendor/wifi/hostapd/hostapd_dual5g.conf"
#define CONFIG_FILE_60G "/data/vendor/wifi/hostapd/hostapd_60g.conf"
/** Configuration file name for OWE-transition */
#define CONFIG_FILE_OWE "/data/vendor/wifi/hostapd/hostapd_owe.conf"
/** Configuration file name */ /** Configuration file name */
#define CONFIG_FILE "/data/vendor/wifi/hostapd/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 "/vendor/etc/hostapd/hostapd_default.conf"
/** Default Accept list file name */ /** Default Accept list file name */
#define DEFAULT_ACCEPT_LIST_FILE_PATH "/system/etc/hostapd/hostapd.accept" #define DEFAULT_ACCEPT_LIST_FILE_PATH "/vendor/etc/hostapd/hostapd.accept"
/** Accept list file name */ /** Accept list file name */
#define ACCEPT_LIST_FILE "/data/vendor/wifi/hostapd/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 "/vendor/etc/hostapd/hostapd.deny"
/** Deny list file name */ /** Deny list file name */
#define DENY_LIST_FILE "/data/vendor/wifi/hostapd/hostapd.deny" #define DENY_LIST_FILE "/data/vendor/wifi/hostapd/hostapd.deny"
@@ -252,6 +257,8 @@ enum eCmd_req {
enum eConf_req { enum eConf_req {
CONF_2g = 0, CONF_2g = 0,
CONF_5g = 1, CONF_5g = 1,
CONF_owe = 2,
CONF_60g = 3,
CONF_REQ_LAST CONF_REQ_LAST
}; };
@@ -354,6 +361,13 @@ typedef enum esap_cmd {
eCMD_WOWLAN_TRIGGERS = 80, eCMD_WOWLAN_TRIGGERS = 80,
eCMD_ACCEPT_MAC_FILE = 81, eCMD_ACCEPT_MAC_FILE = 81,
eCMD_DENY_MAC_FILE = 82, eCMD_DENY_MAC_FILE = 82,
eCMD_OWE_TRANS_IFNAME = 83,
eCMD_SAE_REQUIRE_MPF = 84,
eCMD_IEEE80211AX = 85,
eCMD_ENABLE_EDMG = 86,
eCMD_EDMG_CHANNEL = 87,
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;
@@ -419,6 +433,7 @@ enum oper_mode {
HW_MODE_N_ONLY = 4, HW_MODE_N_ONLY = 4,
HW_MODE_A = 5, HW_MODE_A = 5,
HW_MODE_ANY = 6, HW_MODE_ANY = 6,
HW_MODE_AD = 7,
HW_MODE_UNKNOWN HW_MODE_UNKNOWN
}; };
@@ -529,7 +544,7 @@ typedef struct sap_auto_channel_info {
/** Validate the pairwise encryption */ /** Validate the pairwise encryption */
#define IS_VALID_PAIRWISE(x) (((!strcmp(x, "TKIP")) || (!strcmp(x, "CCMP")) || \ #define IS_VALID_PAIRWISE(x) (((!strcmp(x, "TKIP")) || (!strcmp(x, "CCMP")) || \
(!strcmp(x, "TKIP CCMP")) || (!strcmp(x, "CCMP TKIP"))) ? TRUE : FALSE) (!strcmp(x, "TKIP CCMP")) || (!strcmp(x, "CCMP TKIP")) || (!strcmp(x, "GCMP"))) ? TRUE : FALSE)
/** Validate the WMM status */ /** Validate the WMM status */
#define IS_VALID_WMM_STATE(x) (((x >= WMM_AUTO_IN_INI) && (x <= WMM_DISABLED_IN_INI)) ? TRUE: FALSE) #define IS_VALID_WMM_STATE(x) (((x >= WMM_AUTO_IN_INI) && (x <= WMM_DISABLED_IN_INI)) ? TRUE: FALSE)