blob: 064e499047ab506f03f7f47e02dc37e7e46b0993 [file] [log] [blame]
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001/*
Deepthi Gowrid0ea69c2012-12-26 14:08:38 +05302 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
Deepthi Gowrid0ea69c2012-12-26 14:08:38 +053013 * * Neither the name of The Linux Foundation, Inc. nor the names of its
Raj Kushwahaaaaa5182010-08-25 14:12:16 -070014 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30
31#include <stdio.h>
32#include <string.h>
33#include <stdlib.h>
Deepthi Gowrid4c03152012-07-17 18:42:07 +053034#include <errno.h>
Raj Kushwahaaaaa5182010-08-25 14:12:16 -070035#include <unistd.h>
36#include <ctype.h>
37#include <netinet/in.h>
38#include <arpa/inet.h>
39#include <linux/wireless.h>
40#include <sys/socket.h>
41#include <sys/un.h>
42#include <sys/select.h>
Raj Kushwahaae27f822010-11-14 17:47:11 -080043#include <sys/stat.h>
Raj Kushwahaaaaa5182010-08-25 14:12:16 -070044#include <sys/types.h>
45#include <unistd.h>
Nalla Kartheekf4eef252016-04-29 18:09:35 +053046#include <net/if.h>
Purushottam Kushwaha0e5ec062017-07-21 22:11:45 +053047#include <net/if_arp.h>
Nalla Kartheekf4eef252016-04-29 18:09:35 +053048#include <netlink/netlink.h>
49#include <netlink/genl/genl.h>
50#include <netlink/genl/family.h>
51#include <netlink/genl/ctrl.h>
52#include "nl80211_copy.h"
Raj Kushwahaaaaa5182010-08-25 14:12:16 -070053
54#include "qsap_api.h"
55#include "qsap.h"
56
Deepthi Gowri6ce57562012-06-27 01:18:15 +053057#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+1)
Deepthi Gowri684d2f92012-05-23 23:28:16 +053058#define WLAN_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -070059#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV+9)
60#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV+10)
61#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV+11)
Raj Kushwaha41027212010-10-13 00:11:12 -070062#define QCSAP_IOCTL_AP_STATS (SIOCIWFIRSTPRIV+12)
Deepthi Gowri684d2f92012-05-23 23:28:16 +053063#define QCSAP_IOCTL_SET_CHANNEL_RANGE (SIOCIWFIRSTPRIV+17)
Deepthi Gowri6ce57562012-06-27 01:18:15 +053064#define QCSAP_PARAM_GET_AUTO_CHANNEL 9
Deepthi Gowri684d2f92012-05-23 23:28:16 +053065#define WE_SET_SAP_CHANNELS 3
Raj Kushwahaaaaa5182010-08-25 14:12:16 -070066
Ajit Vaishyaa21d2652017-07-04 21:32:27 +053067#define LOG_TAG "QCSDK"
Raj Kushwahaaaaa5182010-08-25 14:12:16 -070068
Veerendranath Jakkamc613ebb2018-05-18 18:41:15 +053069#include <cutils/properties.h>
70#include <cutils/log.h>
Raj Kushwahaaaaa5182010-08-25 14:12:16 -070071
Raj Kushwahaaaaa5182010-08-25 14:12:16 -070072#define SKIP_BLANK_SPACE(x) {while(*x != '\0') { if((*x == ' ') || (*x == '\t')) x++; else break; }}
73
74/** If this variable is enabled, the soft AP is reloaded, after the commit
75 * command is received */
76static volatile int gIniUpdated = 0;
77
78/** Supported command requests.
79 * WANRING: The enum eCMD_REQ in the file qsap_api.h should be
80 * updated if Cmd_req[], us updated
81 */
82s8 *Cmd_req[eCMD_REQ_LAST] = {
83 "get",
84 "set"
85};
86
Ajit Vaishyaa21d2652017-07-04 21:32:27 +053087/** Supported config file requests.
88 * WANRING: The enum eConf_req in the file qsap_api.h should be
89 * updated if Conf_req[], us updated
90 */
91s8 *Conf_req[CONF_REQ_LAST] = {
92 "dual2g",
Hu Wangd8555002018-12-06 18:13:00 +080093 "dual5g",
Dedy Lanskya2dd08f2019-11-10 13:58:58 +020094 "owe",
95 "60g",
Ajit Vaishyaa21d2652017-07-04 21:32:27 +053096};
97
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -080098/*
99 * WARNING: On updating the cmd_list, the enum esap_cmd in file
100 * qsap_api.h must be updates to reflect the changes
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700101 */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800102static struct Command cmd_list[eCMD_LAST] = {
103 { "ssid", "QualcommSoftAP" },
104 { "ignore_broadcast_ssid", "0" },
105 { "channel", "1" },
106 { "beacon_int", "100" },
107 { "dtim_period", "2" },
108 { "hw_mode", "n" },
109 { "auth_algs", "3" },
110 { "security_mode", "0" },
111 { "wep_key0", NULL },
112 { "wep_key1", NULL },
113 { "wep_key2", NULL },
114 { "wep_key3", NULL },
115 { "wep_default_key", NULL },
116 { "wpa_passphrase", NULL },
117 { "wpa_pairwise", NULL },
118 { "rsn_pairwise", NULL },
119 { "mac_address", "00deadbeef04" },
120 { "reset_ap", NULL },
121 { "macaddr_acl", "0" },
122 { "add_to_allow_list", NULL },
123 { "add_to_deny_list", NULL },
124 { "remove_from_allow_list", NULL },
125 { "remove_from_deny_list", NULL },
126 { "allow_list", "" },
127 { "deny_list", "" },
128 { "commit", NULL },
129 { "enable_softap", NULL },
130 { "disassoc_sta", NULL },
131 { "reset_to_default", NULL },
132 { "protection_flag", "1" },
133 { "data_rate", "0" },
134 { "sta_mac_list", NULL },
135 { "tx_power", "27" },
136 { "sdk_version", SDK_VERSION },
137 { "wmm_enabled", "0" },
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700138
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800139 /** Warning: Do not change the order of the WPS commands */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800140 { "wps_state", "0" },
141 { "config_methods", NULL },
142 { "uuid", NULL },
143 { "device_name", NULL },
144 { "manufacturer", NULL },
145 { "model_name", NULL },
146 { "model_number", NULL },
147 { "serial_number", NULL },
148 { "device_type", NULL },
149 { "os_version", NULL },
150 { "friendly_name", NULL },
151 { "manufacturer_url", NULL },
152 { "model_description", NULL },
153 { "model_url", NULL },
154 { "upc", NULL },
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700155 /************ WPS commands end *********/
156
Raj Kushwahaae27f822010-11-14 17:47:11 -0800157 { "fragm_threshold", NULL },
158 { "rts_threshold", NULL },
159 { "wpa_group_rekey", NULL },
160 { "country_code", NULL },
Deepthi Gowri6344a802012-01-12 17:11:18 +0530161 { "ap_isolate", NULL },
Santosh Sajjanc463f732011-12-22 18:24:56 +0530162 { "ieee80211d", NULL },
Raj Kushwahaae27f822010-11-14 17:47:11 -0800163 { "apstat", NULL },
164 { "auto_shut_off_time", NULL },
165 { "energy_detect_threshold", "128" },
Santosh Sajjanc463f732011-12-22 18:24:56 +0530166 { "basic_rates", NULL },
167 { "require_ht", NULL },
168 { "ieee80211n", "1" },
Deepthi Gowri684d2f92012-05-23 23:28:16 +0530169 { "setchannelrange", NULL },
Deepthi Gowri6ce57562012-06-27 01:18:15 +0530170 { "autochannel", NULL },
Chet Lanctot4c15b562013-07-25 11:02:06 -0700171 { "ieee80211w", NULL },
Chet Lanctot7a2827f2013-09-09 17:48:58 -0700172 { "wpa_key_mgmt", NULL },
Changzhi Dengfddc6be2015-05-21 15:47:07 +0800173 { "max_num_sta", "8" },
Manikandan Mohane1bfb732015-08-18 16:30:11 -0700174 { "ieee80211ac", NULL },
175 { "vht_oper_chwidth", NULL },
176 { "chanlist", NULL },
177 { "ht_capab", NULL },
Pradeep Reddy POTTETI5c1a3ab2016-01-07 20:01:40 +0530178 { "ieee80211h", NULL },
Dedy Lansky350c3532016-05-16 11:54:10 +0300179 { "enable_wigig_softap", NULL },
Nalla Kartheekf4eef252016-04-29 18:09:35 +0530180 { "interface", NULL },
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +0530181 { "ssid2", NULL },
182 { "bridge", NULL },
Ajit Vaishya8c3357c2017-08-11 16:52:38 +0530183 { "ctrl_interface", NULL },
Ajit Vaishya3f875322017-08-14 22:31:29 +0530184 { "vendor_elements", NULL },
185 { "assocresp_elements", NULL },
Purushottam Kushwaha68e72482018-08-20 12:18:04 +0530186 { "acs_exclude_dfs", NULL },
Abhishek Srivastavab44cdad2018-10-23 19:18:50 +0530187 { "wowlan_triggers", "any" },
188 { "accept_mac_file", NULL },
189 { "deny_mac_file", NULL },
Hu Wangaa4c6ca2018-11-26 18:26:00 +0800190 { "owe_transition_ifname", NULL },
Hu Wang62ae34e2019-01-31 10:26:14 +0800191 { "sae_require_mfp", NULL },
Dedy Lanskya2dd08f2019-11-10 13:58:58 +0200192 { "ieee80211ax", NULL },
Alexei Avshalom Lazar1b6053c2019-11-14 11:33:49 +0200193 { "enable_edmg", NULL },
194 { "edmg_channel", NULL },
Abhishek Srivastavab44cdad2018-10-23 19:18:50 +0530195
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700196};
197
Raj Kushwahaae27f822010-11-14 17:47:11 -0800198struct Command qsap_str[eSTR_LAST] = {
199 { "wpa", NULL },
200 { "accept_mac_file", NULL },
201 { "deny_mac_file", NULL },
202 { "gAPMacAddr", "00deadbeef04" },/** AP MAC address */
203 { "gEnableApProt", "1" },/** protection flag in ini file */
204 { "gFixedRate", "0" },/** Fixed rate in ini */
205 { "gTxPowerCap", "27" },/** Tx power in ini */
206 { "gFragmentationThreshold", "2346" },/** Fragmentation threshold in ini */
207 { "RTSThreshold", "2347" },/** RTS threshold in ini */
208 { "gAPCntryCode", "USI" },/** Country code in ini */
209 { "gDisableIntraBssFwd", "0" },/** Intra-bss forward in ini */
210 { "WmmIsEnabled", "0" },/** WMM */
211 { "g11dSupportEnabled", "1" },/** 802.11d support */
212 { "ieee80211n", NULL },
213 { "ctrl_interface", NULL },
214 { "interface", NULL },
215 { "eap_server", NULL },
216 { "gAPAutoShutOff", "0" },
217 { "gEnablePhyAgcListenMode", "128" },
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700218};
219
220/** Supported operating mode */
221char *hw_mode[HW_MODE_UNKNOWN] = {
Dedy Lansky59c014f2019-08-08 09:58:36 +0300222 "b", "g", "n", "g-only", "n-only", "a", "any", "ad"
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700223};
224
225/** configuration file path */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800226char *pconffile = CONFIG_FILE;
Deepthi Gowriae5a4f72012-01-31 19:39:06 +0530227char *fIni = WIFI_DRIVER_CONF_FILE;
Anh Nguyen43cf2be2013-09-23 09:04:29 -0700228s8 ini_file[PROPERTY_VALUE_MAX] = {0};
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700229
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800230static int qsap_scnprintf(char *str, size_t size, const char *format, ...)
231{
232 va_list arg_ptr;
233 int ret = 0;
234
235 if (size < 1)
236 return 0;
237 va_start(arg_ptr, format);
238 ret = vsnprintf(str, size, format, arg_ptr);
239 va_end(arg_ptr);
240 return (ret < (int)size) ? ret : (int)(size - 1);
241}
242
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700243/**
244 * @brief
245 * For a give configuration parameter, read the configuration value from the file.
246 * @param pfile [IN] configuration file path
Raj Kushwahaae27f822010-11-14 17:47:11 -0800247 * @param pcmd [IN] pointer to the comand structure
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700248 * @param presp [OUT] buffer to store the configuration value
249 * @param plen [IN-OUT] The length of the buffer is provided as input.
250 * The length of the configuration parameter value, stored
251 * in the 'presp', is provided as the output
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700252 * @param ignore_comment [IN] if set, read the commented value also
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800253 * @return void
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700254*/
Raj Kushwahaae27f822010-11-14 17:47:11 -0800255static s32 qsap_read_cfg(s8 *pfile, struct Command * pcmd, s8 *presp, u32 *plen, s8 *var, s32 ignore_comment)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700256{
257 FILE *fcfg;
258 s8 buf[MAX_CONF_LINE_LEN];
259 u16 len;
260 s8 *val;
261
262 /** Open the configuration file */
263 fcfg = fopen(pfile, "r");
264
265 if(NULL == fcfg) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530266 ALOGE("%s : unable to open file \n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800267 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_RES_UNAVAILABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700268 return eERR_FILE_OPEN;
269 }
270
271 /** Read the line from the configuration file */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800272 len = strlen(pcmd->name);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700273 while(NULL != fgets(buf, MAX_CONF_LINE_LEN, fcfg)) {
274 s8 *pline = buf;
275
Peng Xu4d42a1d2017-09-19 11:04:49 -0700276 if (strlen(buf) == 0)
277 continue;
278
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700279 /** Skip the commented lines */
280 if(buf[0] == '#') {
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700281 if (ignore_comment) {
282 pline++;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800283 }
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700284 else continue;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700285 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800286
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700287 /** Identify the configuration parameter in the configuration file */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800288 if(!strncmp(pline, pcmd->name, len) && (pline[len] == '=')) {
289 int tmp_indx;
290
291 /* Delate all \r \n combinations infront of the config string */
292 tmp_indx = strlen(buf)-1;
293 while( (buf[tmp_indx] == '\r') || (buf[tmp_indx] == '\n') ) tmp_indx--;
294
295 buf[tmp_indx+1] = '\0';
296
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700297 if ( NULL != var ) {
298 val = strchr(pline, '=');
299 if(NULL == val)
300 break;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800301 *plen = qsap_scnprintf(presp, *plen, "%s %s%s", SUCCESS, var, val);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700302 }
303 else {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800304 *plen = qsap_scnprintf(presp, *plen, "%s %s", SUCCESS, pline);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700305 }
306 fclose(fcfg);
307 return eSUCCESS;
308 }
309 }
310
Raj Kushwahaae27f822010-11-14 17:47:11 -0800311#if 0
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700312 /** Configuration parameter is absent in the file */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800313 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_FEATURE_NOT_ENABLED);
Raj Kushwahaae27f822010-11-14 17:47:11 -0800314#else
315 /** Value not found in the configuration file */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800316 /** Send the default value, if we are reading from ini file */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800317 if ( pcmd->default_value ) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800318 *plen = qsap_scnprintf(presp, *plen, "%s %s=%s", SUCCESS, var?var:pcmd->name, pcmd->default_value);
Raj Kushwahaae27f822010-11-14 17:47:11 -0800319 fclose(fcfg);
320 return eSUCCESS;
321 }
322 else {
323 /** Configuration parameter is absent in the file */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800324 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_FEATURE_NOT_ENABLED);
Raj Kushwahaae27f822010-11-14 17:47:11 -0800325 }
326#endif
327
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700328 fclose(fcfg);
329
330 return eERR_CONFIG_PARAM_MISSING;
331}
332
333/**
334 * @brief
335 * Write the configuration parameter value into the configuration file.
336 * @param pfile [IN] configuration file path.
337 * @param pcmd [IN] command name
338 * @param pVal [IN] configuration parameter to be written to the file.
339 * @param presp [OUT] buffer to store the configuration value.
340 * @param plen [IN-OUT] The length of the buffer is provided as input.
341 * The length of the configuration parameter value, stored
342 * in the 'presp', is provided as the output
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800343 * @return void
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700344*/
Raj Kushwahaae27f822010-11-14 17:47:11 -0800345static s32 qsap_write_cfg(s8 *pfile, struct Command * pcmd, s8 *pVal, s8 *presp, u32 *plen, s32 inifile)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700346{
347 FILE *fcfg, *ftmp;
348 s8 buf[MAX_CONF_LINE_LEN+1];
349 s16 len, result = FALSE;
350
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530351 ALOGD("cmd=%s, Val:%s, INI:%ld \n", pcmd->name, pVal, inifile);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700352
353 /** Open the configuration file */
354 fcfg = fopen(pfile, "r");
355 if(NULL == fcfg) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530356 ALOGE("%s : unable to open file \n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800357 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_RES_UNAVAILABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700358 return eERR_FILE_OPEN;
359 }
360
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800361 qsap_scnprintf(buf, sizeof(buf), "%s~", pfile);
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700362
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700363 /** Open a temporary file */
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700364 ftmp = fopen(buf, "w+");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700365 if(NULL == ftmp) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530366 ALOGE("%s : unable to open tmp file \n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800367 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_RES_UNAVAILABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700368 fclose(fcfg);
369 return eERR_FILE_OPEN;
370 }
371
372 /** Read the values from the configuration file */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800373 len = strlen(pcmd->name);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700374 while(NULL != fgets(buf, MAX_CONF_LINE_LEN, fcfg)) {
375 s8 *pline = buf;
376
377 /** commented line */
378 if(buf[0] == '#')
379 pline++;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800380
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700381 /** Identify the configuration parameter to be updated */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800382 if((!strncmp(pline, pcmd->name, len)) && (result == FALSE)) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700383 if(pline[len] == '=') {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800384 qsap_scnprintf(buf, sizeof(buf), "%s=%s\n", pcmd->name, pVal);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700385 result = TRUE;
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530386 ALOGD("Updated:%s\n", buf);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700387 }
388 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800389
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700390 if(inifile && (!strncmp(pline, "END", 3)))
391 break;
392
393 fprintf(ftmp, "%s", buf);
394 }
395
396 if (result == FALSE) {
397 /* Configuration line not found */
398 /* Add the new line at the end of file */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800399 qsap_scnprintf(buf, sizeof(buf), "%s=%s\n", pcmd->name, pVal);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700400 fprintf(ftmp, "%s", buf);
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530401 ALOGD("Adding a new line in %s file: [%s] \n", inifile ? "inifile" : "hostapd.conf", buf);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700402 }
403
404 if(inifile) {
405 gIniUpdated = 1;
406 fprintf(ftmp, "END\n");
407 while(NULL != fgets(buf, MAX_CONF_LINE_LEN, fcfg))
408 fprintf(ftmp, "%s", buf);
409 }
410
411 fclose(fcfg);
412 fclose(ftmp);
413
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800414 qsap_scnprintf(buf, sizeof(buf), "%s~", pfile);
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700415
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700416 /** Restore the updated configuration file */
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700417 result = rename(buf, pfile);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700418
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800419 *plen = qsap_scnprintf(presp, *plen, "%s", (result == eERR_UNKNOWN) ? ERR_FEATURE_NOT_ENABLED : SUCCESS);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700420
421 /** Remove the temporary file. Dont care the return value */
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700422 unlink(buf);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700423
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530424 /* chmod is needed because open() didn't set permisions properly */
425 if (chmod(pfile, 0660) < 0) {
426 ALOGE("Error changing permissions of %s to 0660: %s",
427 pfile, strerror(errno));
428 unlink(pfile);
429 return -1;
430 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700431 if(result == eERR_UNKNOWN)
432 return eERR_FEATURE_NOT_ENABLED;
433
434 return eSUCCESS;
435}
436
437/**
438 * @brief Read the security mode set in the configuration
439 * @param pfile [IN] configuration file path.
440 * @param presp [OUT] buffer to store the security mode.
441 * @param plen [IN-OUT] The length of the buffer is provided as input.
442 * The length of the security mode value, stored
443 * in the 'presp', is provided as the output
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800444 * @return void
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700445*/
446static sec_mode_t qsap_read_security_mode(s8 *pfile, s8 *presp, u32 *plen)
447{
448 sec_mode_t mode;
449 u32 temp = *plen;
450
451 /** Read the WEP default key */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800452 qsap_read_cfg(pfile, &cmd_list[eCMD_DEFAULT_KEY], presp, plen, NULL, GET_ENABLED_ONLY);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700453
454 if ( !strcmp(presp, ERR_FEATURE_NOT_ENABLED) ) {
455 *plen = temp;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800456
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700457 /* WEP, is not enabled */
458
459 /** Read WPA security status */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800460 qsap_read_cfg(pfile, &qsap_str[STR_WPA], presp, plen, NULL, GET_ENABLED_ONLY);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700461 if ( !strcmp(presp, ERR_FEATURE_NOT_ENABLED) ) {
462 /** WPA is disabled, No security */
463 mode = SEC_MODE_NONE;
464 }
465 else {
466 /** WPA, WPA2 or WPA-WPA2 mixed security */
467 s8 * ptmp = presp;
468 while((*plen)-- && (*ptmp++ != '=') );
469 mode = *plen ? (
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800470 *ptmp == '1' ? SEC_MODE_WPA_PSK :
471 *ptmp == '2' ? SEC_MODE_WPA2_PSK :
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700472 *ptmp == '3' ? SEC_MODE_WPA_WPA2_PSK : SEC_MODE_INVALID ): SEC_MODE_INVALID;
473 }
474 }
475 else {
476 /** Verify if, WPA is disabled */
477 *plen = temp;
Raj Kushwahaae27f822010-11-14 17:47:11 -0800478 qsap_read_cfg(pfile, &qsap_str[STR_WPA], presp, plen, NULL, GET_ENABLED_ONLY);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700479 if ( !strcmp(presp, ERR_FEATURE_NOT_ENABLED) ) {
480 /** WPA is disabled, hence WEP is enabled */
481 mode = SEC_MODE_WEP;
482 }
483 else {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800484 *plen = qsap_scnprintf(presp, temp, "%s", ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700485 return SEC_MODE_INVALID;
486 }
487 }
488
489 if(mode != SEC_MODE_INVALID) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800490 *plen = qsap_scnprintf(presp, temp,"%s %s=%d", SUCCESS, cmd_list[eCMD_SEC_MODE].name, mode);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700491 }
492 else {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800493 *plen = qsap_scnprintf(presp, temp,"%s", ERR_NOT_SUPPORTED);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700494 }
495
496 return mode;
497}
498
499/**
500 * @brief
501 * Enable or disable a configuration parameter in the configuration file.
502 * @param pfile [IN] configuration file name
Raj Kushwahaae27f822010-11-14 17:47:11 -0800503 * @param pcmd [IN] configuration command structure
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700504 * @param status [IN] status to be set. The valid values are 'ENABLE' or 'DISABLE'
505 * @return On success, return 0
506 * On failure, return -1
507*/
Raj Kushwahaae27f822010-11-14 17:47:11 -0800508static s32 qsap_change_cfg(s8 *pfile, struct Command * pcmd, u32 status)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700509{
510 FILE *fcfg, *ftmp;
511 s8 buf[MAX_CONF_LINE_LEN+1];
512 u16 len;
513
514 /** Open the configuartion file */
515 fcfg = fopen(pfile, "r");
516 if(NULL == fcfg) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530517 ALOGE("%s : unable to open file \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700518 return eERR_UNKNOWN;
519 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800520
521 qsap_scnprintf(buf, sizeof(buf), "%s~", pfile);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700522
523 /** Open a temporary file */
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700524 ftmp = fopen(buf, "w");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700525 if(NULL == ftmp) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530526 ALOGE("%s : unable to open tmp file \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700527 fclose(fcfg);
528 return eERR_UNKNOWN;
529 }
530
531 /** Read the configuration parameters from the configuration file */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800532 len = strlen(pcmd->name);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700533 while(NULL != fgets(buf+1, MAX_CONF_LINE_LEN, fcfg)) {
534 s8 *p = buf+1;
535
536 /** Commented line */
537 if(p[0] == '#')
538 p++;
539
540 /** Identify the configuration parameter */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800541 if(!strncmp(p, pcmd->name, len)) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700542 if(p[len] == '=') {
543 if(status == DISABLE) {
544 fprintf(ftmp, "#%s", p);
545 }
546 else {
547 fprintf(ftmp, "%s", p);
548 }
549 continue;
550 }
551 }
552 fprintf(ftmp, "%s", buf+1);
553 }
554
555 fclose(fcfg);
556 fclose(ftmp);
557
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800558 qsap_scnprintf(buf, sizeof(buf), "%s~", pfile);
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700559
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700560 /** Restore the new configuration file */
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700561 if(eERR_UNKNOWN == rename(buf, pfile)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530562 ALOGE("unable to rename the file \n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700563 return eERR_UNKNOWN;
564 }
565
566 /** Delete the temporary file */
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700567 unlink(buf);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700568
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530569 /* chmod is needed because open() didn't set permisions properly */
570 if (chmod(pfile, 0660) < 0) {
571 ALOGE("Error changing permissions of %s to 0660: %s",
572 pfile, strerror(errno));
573 unlink(pfile);
574 return -1;
575 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700576 return 0;
577}
578
579/**
580 * @brief
581 * Set the security mode in the configuration. The security mode
582 * can be :
583 * 1. No security
584 * 2. WEP
585 * 3. WPA
586 * 4. WPA2
587 * 5. WPA and WPA2 mixed mode
588 * @param pfile [IN] configuration file name
589 * @param sec_mode [IN] security mode to be set
590 * @param presp [OUTPUT] presp The command output format :
591 * On success,
592 * success <cmd>=<value>
593 * On failure,
594 * failure <error message>
595 * @param plen [IN-OUT] plen
596 * [IN] The length of the buffer, presp
597 * [OUT] The length of the response in the buffer, presp
598 * @return void
599*/
600static void qsap_set_security_mode(s8 *pfile, u32 sec_mode, s8 *presp, u32 *plen)
601{
602 s16 wep, wpa;
603 s8 sec[MAX_INT_STR];
604 s32 rsn_status = DISABLE;
605 s32 ret = eERR_UNKNOWN;
606
607 /** Is valid security mode ? */
608 if(sec_mode >= SEC_MODE_INVALID) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800609 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700610 return;
611 }
612
613 /** No security */
614 if(SEC_MODE_NONE == sec_mode) {
615 wep = DISABLE;
616 wpa = DISABLE;
617 }
618 /** WEP security */
619 else if(SEC_MODE_WEP == sec_mode) {
620 wep = ENABLE;
621 wpa = DISABLE;
622 }
623 else {
624 /** WPA, WPA2 and mixed-mode security */
625 u16 wpa_val;
626 u32 tmp = *plen;
627
628 wep = DISABLE;
629 wpa = ENABLE;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800630
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700631 if(sec_mode == SEC_MODE_WPA_PSK)
632 wpa_val = WPA_IN_CONF_FILE;
633
634 else if(sec_mode == SEC_MODE_WPA2_PSK) {
635 wpa_val = WPA2_IN_CONF_FILE;
636 rsn_status = ENABLE;
637 }
638
639 else if(sec_mode == SEC_MODE_WPA_WPA2_PSK) {
640 wpa_val = WPA_WPA2_IN_CONF_FILE;
641 rsn_status = ENABLE;
642 }
643
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800644 qsap_scnprintf(sec, sizeof(sec), "%u", wpa_val);
Santosh Sajjan47e3a842011-12-10 21:11:12 +0530645 qsap_write_cfg(pfile, &qsap_str[STR_WPA], sec, presp, plen, HOSTAPD_CONF_QCOM_FILE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700646 *plen = tmp;
647 }
648
649 /** The configuration parameters for the security to be set are enabled
650 * and the configuration parameters for the other security types are
651 * disabled in the configuration file
652 */
Raj Kushwahaae27f822010-11-14 17:47:11 -0800653 if(eERR_UNKNOWN == qsap_change_cfg(pfile, &cmd_list[eCMD_DEFAULT_KEY], wep)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530654 ALOGE("%s: wep_default_key error\n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700655 goto end;
656 }
657
Raj Kushwahaae27f822010-11-14 17:47:11 -0800658 if(eERR_UNKNOWN == qsap_change_cfg(pfile, &cmd_list[eCMD_WEP_KEY0], wep)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530659 ALOGE("%s: CMD_WEP_KEY0 \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700660 goto end;
661 }
662
Raj Kushwahaae27f822010-11-14 17:47:11 -0800663 if(eERR_UNKNOWN == qsap_change_cfg(pfile, &cmd_list[eCMD_WEP_KEY1], wep)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530664 ALOGE("%s: CMD_WEP_KEY1 \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700665 goto end;
666 }
667
Raj Kushwahaae27f822010-11-14 17:47:11 -0800668 if(eERR_UNKNOWN == qsap_change_cfg(pfile, &cmd_list[eCMD_WEP_KEY2], wep)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530669 ALOGE("%s: CMD_WEP_KEY2 \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700670 goto end;
671 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800672
Raj Kushwahaae27f822010-11-14 17:47:11 -0800673 if(eERR_UNKNOWN == qsap_change_cfg(pfile, &cmd_list[eCMD_WEP_KEY3], wep)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530674 ALOGE("%s: CMD_WEP_KEY3 \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700675 goto end;
676 }
677
Raj Kushwahaae27f822010-11-14 17:47:11 -0800678 if(eERR_UNKNOWN == qsap_change_cfg(pfile, &cmd_list[eCMD_PASSPHRASE], wpa)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530679 ALOGE("%s: Passphrase error\n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700680 goto end;
681 }
682
683 if((sec_mode != SEC_MODE_NONE) && (sec_mode != SEC_MODE_WEP)) {
684 u32 state = !rsn_status;
685
686 if(sec_mode == SEC_MODE_WPA_WPA2_PSK) state = ENABLE;
687
Raj Kushwahaae27f822010-11-14 17:47:11 -0800688 if(eERR_UNKNOWN == qsap_change_cfg(pfile, &cmd_list[eCMD_WPA_PAIRWISE], state)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530689 ALOGE("%s: WPA Pairwise\n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700690 goto end;
691 }
692 }
693
Raj Kushwahaae27f822010-11-14 17:47:11 -0800694 if(eERR_UNKNOWN == qsap_change_cfg(pfile, &cmd_list[eCMD_RSN_PAIRWISE], rsn_status)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530695 ALOGE("%s: WPA2 Pairwise\n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700696 goto end;
697 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800698
Raj Kushwahaae27f822010-11-14 17:47:11 -0800699 if(eERR_UNKNOWN == qsap_change_cfg(pfile, &qsap_str[STR_WPA], wpa)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530700 ALOGE("%s: WPA\n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700701 goto end;
702 }
703
704 ret = eSUCCESS;
705
706end:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800707 *plen = qsap_scnprintf(presp, *plen, "%s", (ret == eSUCCESS) ? SUCCESS : ERR_UNKNOWN);
708
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700709 return;
710}
711
712/**
713 * @brief
714 * Get the file path having the allow or deny MAC address list
715 * @param pcfgfile [IN] configuration file name
716 * @param pcmd [IN] pcmd pointer to the command string
717 * @param pfile [OUT] buffer to store the return value, containing the file name
718 * or the error message.
719 * @param plen [IN-OUT] size of the buffer 'pfile', is provided as input and
720 * the length of the file name is returned as output
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800721 * @return
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700722 * On success, a pointer to the file name in the buffer 'pfile'.
723 * On failure, NULL is returned
724*/
Raj Kushwahaae27f822010-11-14 17:47:11 -0800725static s8 *qsap_get_allow_deny_file_name(s8 *pcfgfile, struct Command * pcmd, s8 *pfile, u32 *plen)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700726{
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700727 if(eSUCCESS == qsap_read_cfg(pcfgfile, pcmd, pfile, plen, NULL, GET_ENABLED_ONLY)) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700728 return strchr(pfile, '=') + 1;
729 }
730
731 return NULL;
732}
733
c_rrajive629e822015-07-20 15:21:20 +0530734int qsap_hostd_exec(int argc, char ** argv) {
735
736#define MAX_CMD_SIZE 256
737 char qcCmdBuf[MAX_CMD_SIZE], *pCmdBuf;
738 u32 len = MAX_CMD_SIZE;
739 int i = 2, ret;
740
741 if ( argc < 4 ) {
742 ALOGD("failure: invalid arguments");
743 return -1;
744 }
745
746 argc -= 2;
747 pCmdBuf = qcCmdBuf;
748
749 while (argc--) {
750 ret = snprintf(pCmdBuf, len, " %s", argv[i]);
751 if ((ret < 0) || (ret >= (int)len)) {
752 /* Error case */
753 /* TODO: Command too long send the error message */
754 *pCmdBuf = '\0';
755 break;
756 }
757 ALOGD("argv[%d] (%s)",i, argv[i]);
758 pCmdBuf += ret;
759 len -= ret;
760 i++;
761 }
762
763 ALOGD("QCCMD data (%s)", pCmdBuf);
764 len = MAX_CMD_SIZE;
765 qsap_hostd_exec_cmd(qcCmdBuf, qcCmdBuf, (u32*)&len);
766 return 0;
767}
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700768/** Function to identify a valid MAC address */
769static int isValid_MAC_address(char *pMac)
770{
771 int i, len;
772
773 len = strlen(pMac);
774
775 if(len < MAC_ADDR_LEN)
776 return FALSE;
777
778 for(i=0; i<MAC_ADDR_LEN; i++) {
779 switch(i) {
780 case 2: case 5: case 8: case 11: case 14:
781 if(pMac[i] != ':')
782 return FALSE;
783 break;
784 default:
785 if(isxdigit(pMac[i]) == 0)
786 return FALSE;
787 }
788 }
789
790 return TRUE;
791}
792
793/**
794 * @brief
795 * Add a given MAC address to the allow or deny MAC list file.
796 * A maximum of 15 MAC addresses are allowed in the list. If the input
797 * MAC addresses are more than the allowed number, then the allowed number
798 * of MAC addresses are updated to the MAC list file and the remaining
799 * MAC addresses are discarded
800 *
801 * @param pfile [IN] Path of the allow or deny MAC list file
802 * @param pVal [IN] A string containing one or more MAC addresses. Multiple
803 * MAC addresses are separated by a SPACE separator
804 * Ex. "11:22:33:44:55:66 77:88:99:00:88:00"
805 * @param presp [OUT] buffer to store the response
806 * @param plen [IN-OUT] The length of the buffer 'presp' is provided as input.
807 * The length of the response, stored in buffer 'presp' is
808 * provided as output.
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800809 * @return void
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700810*/
811static void qsap_add_mac_to_file(s8 *pfile, s8 *pVal, s8 *presp, u32 *plen)
812{
813 s32 len;
814 s16 num_macs = 0;
815 s8 buf[32];
816 s8 macbuf[32];
817 FILE *fp;
818
819 /** Create the file if it does not exists and open it for reading */
820 fp = fopen(pfile, "a");
821 if(NULL != fp) {
822 fclose(fp);
823 fp = fopen(pfile, "r+");
824 }
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700825
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700826 if(NULL == fp) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530827 ALOGE("%s : unable to open the file \n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800828 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_RES_UNAVAILABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700829 return;
830 }
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700831
832 /** count the MAC address in the MAC list file */
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700833 while(NULL != (fgets(buf, 32, fp))) {
834 num_macs++;
835 }
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700836
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700837 /** Evaluate the allowed limit */
838 if(num_macs >= MAX_ALLOWED_MAC) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530839 ALOGE("%s : File is full\n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800840 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700841 fclose(fp);
842 return;
843 }
844
845 /** Update all the input MAC addresses into the MAC list file */
846 len = strlen(pVal);
847 while(len > 0) {
848 int i = 0;
849
850 /** Get a MAC address from the input string */
851 while((*pVal != ' ' ) && (*pVal != '\0')) {
852 macbuf[i] = *pVal;
853 i++;
854 pVal++;
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700855
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700856 if(i == MAC_ADDR_LEN)
857 break;
858 }
859 macbuf[i] = '\0';
860 pVal++;
861
862 /** Is valid MAC address input ? */
863 if(TRUE == isValid_MAC_address(macbuf)) {
864
865 /** Append the MAC address to the file */
866 fprintf(fp, "%s\n", macbuf);
867 num_macs++;
868
869 /** Evaluate with the allowed limit */
870 if(num_macs == MAX_ALLOWED_MAC) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530871 ALOGE("MAC file is full now.... \n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700872 break;
873 }
874
875 }
876 len -= strlen(macbuf);
877 if(*pVal != '\0')
878 len--;
879 }
880
881 fclose(fp);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800882
883 *plen = qsap_scnprintf(presp, *plen, "%s", SUCCESS);
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700884
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700885 return;
886}
887
888/**
889 * @brief
890 * Remove one or more MAC addresses from the allow or deny MAC list file.
891 * @param pfile [IN] path of the allow or deny list file.
892 * @param pVal [IN] a list of MAC addresses to be removed from the MAC list file.
893 * @param presp [OUT] the buffer to store the response
894 * @param plen [IN-OUT] The length of the 'presp' buffer is provided as input.
895 * The lenght of the response, stored in 'presp', is
896 * provided as output
897 * @return void
898*/
899static void qsap_remove_from_file(s8 *pfile, s8 *pVal, s8 *presp, u32 *plen)
900{
901 FILE *fp;
902 FILE *ftmp;
903 s8 buf[MAX_CONF_LINE_LEN];
904 int status;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800905
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700906 /** Open the allow or deny MAC list file */
907 fp = fopen(pfile, "r+");
908
909 if(NULL == fp) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530910 ALOGE("%s : unable to open the file \n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800911 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_RES_UNAVAILABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700912 return;
913 }
914
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800915 qsap_scnprintf(buf, sizeof(buf), "%s~", pfile);
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700916
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700917 /** Open a temporary file */
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700918 ftmp = fopen(buf, "w");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700919
920 if(ftmp == NULL) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530921 ALOGE("%s : unable to open the file \n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800922 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_RES_UNAVAILABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700923 fclose(fp);
924 return;
925 }
926
927 /** Read all the MAC addresses from the file */
928 while(NULL != fgets(buf, MAX_CONF_LINE_LEN, fp)) {
929 s8 *plist;
930 s32 slen;
931 int write_back = 1;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800932
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700933 plist = pVal;
934 slen = strlen(pVal);
935
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800936 /** Compare each MAC address in the file with all the
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700937 * input MAC addresses */
938 write_back = 1;
939 while(slen > 0) {
940
941 if(0 == strncmp(buf, plist, MAC_ADDR_LEN)) {
942 write_back = 0;
943 break;
944 }
945
946 while((*plist != ' ') && (*plist != '\0')) {
947 plist++;
948 slen--;
949 }
950
951 while(((*plist == ' ') || (*plist == '\t')) && (*plist != '\0')) {
952 plist++; slen--;
953 }
954 }
955
956 /** Update the file */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800957 if(write_back) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700958 fprintf(ftmp, "%s", buf);
959 }
960 }
961
962 fclose(fp);
963 fclose(ftmp);
964
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800965 qsap_scnprintf(buf, sizeof(buf), "%s~", pfile);
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700966
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700967 /** Restore the configuration file */
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700968 status = rename(buf, pfile);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800969
970 qsap_scnprintf(presp, *plen, "%s", (status == eERR_UNKNOWN) ? ERR_FEATURE_NOT_ENABLED : SUCCESS);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700971
Raj Kushwahaba862bd2010-09-17 00:34:16 -0700972 unlink(buf);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -0800973
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700974 return;
975}
976
977/**
978 * @brief
979 * Identify the MAC list file and the type of updation on the file.
980 * The MAC list file can be : Allow file or Deny file.
981 * The type of operation is : Add to file or Delete from file
982 *
983 * @param file [IN] path of the allow or deny MAC list file.
984 * @param cNum [IN] command number to 'type of file' and the 'type of updation'
985 * to be done.
986 * @param pVal [IN] A list of one or more MAC addresses. Multiple MAC addresses
987 * are separated by a SPACE character
988 * @param presp [OUT] Buffer to store the command response
989 * @param plen [IN-OUT] The length of the 'presp' buffer is provided as input
990 * The length of the response, stored in the 'presp' is provided
991 * as the output
992 * @return void
993*/
994static void qsap_update_mac_list(s8 *pfile, esap_cmd_t cNum, s8 *pVal, s8 *presp, u32 *plen)
995{
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530996 ALOGD("%s : Updating file %s \n", __func__, pfile);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -0700997
998 switch(cNum) {
999 case eCMD_ADD_TO_ALLOW:
1000 case eCMD_ADD_TO_DENY:
1001 qsap_add_mac_to_file(pfile, pVal, presp, plen);
1002 break;
1003
1004 case eCMD_REMOVE_FROM_ALLOW:
1005 case eCMD_REMOVE_FROM_DENY:
1006 qsap_remove_from_file(pfile, pVal, presp, plen);
1007 break;
1008
1009 default:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001010 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001011 return;
1012 }
1013
1014 return;
1015}
1016
1017/**
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001018 * @brief
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001019 * @param fconfig [INPUT] configuration file name
1020 * @param cNum [INPUT] command number. The valid command numbers supported by
1021 * this function are :
1022 * eCMD_ALLOW_LIST - Get the MAC address list from the allow list
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001023 * eCMD_DENY_LIST - Get the MAC address list from the deny list
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001024 * @param presp [OUTPUT] presp The command output format :
1025 * On success,
1026 * success <cmd>=<value>
1027 * On failure,
1028 * failure <error message>
1029 * @param plen [IN-OUT] plen
1030 * [IN] The length of the buffer, presp
1031 * [OUT] The length of the response in the buffer, presp
1032 * @return void
1033**/
1034static void qsap_get_mac_list(s8 *fconfile, esap_cmd_t cNum, s8 *presp, u32 *plen)
1035{
1036 s8 buf[MAX_CONF_LINE_LEN];
1037 FILE *fp;
1038 u32 len_remain;
1039 s8 *pfile, *pOut;
1040 esap_cmd_t sNum;
1041 int cnt = 0;
1042
1043 /** Identify the allow or deny file */
1044 if(eCMD_ALLOW_LIST == cNum) {
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001045 sNum = STR_ACCEPT_MAC_FILE;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001046 }
1047 else if(eCMD_DENY_LIST == cNum) {
1048 sNum = STR_DENY_MAC_FILE;
1049 }
1050 else {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001051 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001052 return;
1053 }
1054
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001055 /** Get the MAC allow or MAC deny file path */
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001056 len_remain = MAX_CONF_LINE_LEN;
Raj Kushwahaae27f822010-11-14 17:47:11 -08001057 if(NULL == (pfile = qsap_get_allow_deny_file_name(fconfile, &qsap_str[sNum], buf, &len_remain))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301058 ALOGE("%s:Unknown error\n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001059 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_RES_UNAVAILABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001060 return;
1061 }
1062
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001063 /** Open allow / deny file, and read the MAC addresses */
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001064 fp = fopen(pfile, "r");
1065 if(NULL == fp) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301066 ALOGE("%s: file open error\n",__func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001067 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_RES_UNAVAILABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001068 return;
1069 }
1070
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001071 *plen -= qsap_scnprintf(presp, *plen, "%s %s=", SUCCESS, cmd_list[cNum].name);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001072
1073 pOut = presp + strlen(presp);
1074
1075 /** Read the MAC address from the MAC allow or deny file */
1076 while(NULL != (fgets(buf, MAX_CONF_LINE_LEN, fp))) {
1077 u32 len;
1078
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001079 /** Avoid the commented lines */
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001080 if(buf[0] == '#')
1081 continue;
1082
1083 if(FALSE == isValid_MAC_address(buf))
1084 continue;
1085
1086 buf[strlen(buf)-1] = '\0';
1087
1088 if(*plen < strlen(buf)) {
1089 *pOut = '\0';
1090 break;
1091 }
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001092
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001093 len = qsap_scnprintf(pOut, *plen, "%s ", buf);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001094 cnt++;
1095
1096 if (cnt >= MAX_ALLOWED_MAC) {
1097 break;
1098 }
1099
1100 pOut += len;
1101 *plen -= len;
1102 }
1103
1104 *plen = strlen(presp);
1105
1106 fclose(fp);
1107
1108 return;
1109}
1110
1111static int qsap_read_mac_address(s8 *presp, u32 *plen)
1112{
1113 char *ptr;
1114 char mac[MAC_ADDR_LEN];
1115 u32 len, i;
1116 int nRet = eERR_INVALID_MAC_ADDR;
1117
1118 len = *plen;
1119
Raj Kushwahaae27f822010-11-14 17:47:11 -08001120 if(eSUCCESS != qsap_read_cfg(fIni, &qsap_str[STR_MAC_IN_INI], presp, plen, cmd_list[eCMD_MAC_ADDR].name, GET_ENABLED_ONLY)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301121 ALOGE("%s :MAC addr read failure \n",__func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001122 goto end;
1123 }
1124
1125 ptr = strchr(presp, '=');
1126 if(NULL == ptr)
1127 goto end;
1128
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +05301129 strlcpy(mac, ptr+1, MAC_ADDR_LEN);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001130 *plen = qsap_scnprintf(presp, len, "%s %s=", SUCCESS, cmd_list[eCMD_MAC_ADDR].name);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001131 ptr = presp + strlen(presp);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001132 len -= strlen(presp); /* decrease the total available buf length */
1133
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001134 for(i=0; i<MAC_ADDR_LEN-5; i+=2) {
1135 u32 tlen;
1136
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001137 tlen = qsap_scnprintf(ptr, len, "%c%c:", mac[i], mac[i+1]);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001138 *plen += tlen;
1139 ptr += tlen;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001140 len -= tlen; /* decrease the available len of ptr */
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001141 }
1142 presp[*plen-1] = '\0';
1143 (*plen)--;
1144
1145 ptr = strchr(presp, '=');
1146 if(NULL == ptr)
1147 goto end;
1148
1149 ptr++;
1150
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301151 ALOGD("MAC :%s \n", ptr);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001152 if(TRUE == isValid_MAC_address(ptr)) {
1153 nRet = eSUCCESS;
1154 }
1155 else {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301156 ALOGE("Invalid MAC in conf file \n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001157 }
1158end:
1159 return nRet;
1160}
1161
Raj Kushwahaae27f822010-11-14 17:47:11 -08001162s8 *qsap_get_config_value(s8 *pfile, struct Command *pcmd, s8 *pbuf, u32 *plen)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001163{
1164 s8 *ptr = NULL;
1165
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001166 if(eSUCCESS == qsap_read_cfg(pfile, pcmd, pbuf, (u32 *)plen, NULL, GET_ENABLED_ONLY)) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001167 ptr = strchr(pbuf, '=');
1168 if(NULL != ptr){
1169 ptr++;
1170 }
1171 else {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301172 ALOGE("Invalid entry, %s\n", pcmd->name);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001173 }
1174 }
1175
1176 return ptr;
1177}
1178
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001179static void qsap_read_wps_state(s8 *presp, u32 *plen)
1180{
1181 u32 tlen = *plen;
1182 s32 status;
1183 s8 *pstate;
1184
Raj Kushwahaae27f822010-11-14 17:47:11 -08001185 if(NULL == (pstate = qsap_get_config_value(pconffile, &cmd_list[eCMD_WPS_STATE], presp, &tlen))) {
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001186 /** unable to read the wps configuration, WPS is disabled !*/
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301187 ALOGD("%s :wps_state not in cfg file \n", __func__);
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001188 status = DISABLE;
1189 }
1190 else {
1191 status = (atoi(pstate) == WPS_STATE_ENABLE) ? ENABLE : DISABLE;
1192 }
1193
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001194 *plen = qsap_scnprintf(presp, *plen, "success %s=%ld", cmd_list[eCMD_WPS_STATE].name, status);
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001195
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001196 return;
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001197}
1198
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001199/**
1200 * Get the channel being used in the soft AP.
1201 */
1202int qsap_get_operating_channel(s32 *pchan)
1203{
1204 int sock;
1205 struct iwreq wrq;
1206 s8 interface[MAX_CONF_LINE_LEN];
1207 u32 len = MAX_CONF_LINE_LEN;
1208 s8 *pif;
1209 int ret;
1210
Raj Kushwaha41027212010-10-13 00:11:12 -07001211 if(ENABLE != is_softap_enabled()) {
1212 goto error;
1213 }
1214
Raj Kushwahaae27f822010-11-14 17:47:11 -08001215 if(NULL == (pif = qsap_get_config_value(pconffile, &qsap_str[STR_INTERFACE], interface, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301216 ALOGE("%s :interface error \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001217 goto error;
1218 }
1219
1220 interface[len] = '\0';
1221
1222 sock = socket(AF_INET, SOCK_DGRAM, 0);
1223 if(sock < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301224 ALOGE("%s :socket error \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001225 goto error;
1226 }
1227
1228 *pchan = 0;
1229
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +05301230 strlcpy(wrq.ifr_name, pif, sizeof(wrq.ifr_name));
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001231 wrq.u.data.length = sizeof(s32);
1232 wrq.u.data.pointer = pchan;
1233 wrq.u.data.flags = 0;
1234
1235 ret = ioctl(sock, QCSAP_IOCTL_GET_CHANNEL, &wrq);
1236 if(ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301237 ALOGE("%s: ioctl failure \n",__func__);
santosh sajjan1a6aff92011-07-18 17:11:12 +05301238 close(sock);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001239 goto error;
1240 }
1241
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301242 ALOGE("Recv len :%d \n", wrq.u.data.length);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301243 *pchan = *(int *)(&wrq.u.name[0]);
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301244 ALOGE("Operating channel :%ld \n", *pchan);
santosh sajjan1a6aff92011-07-18 17:11:12 +05301245 close(sock);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001246 return eSUCCESS;
1247
1248error:
1249 *pchan = 0;
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301250 ALOGE("%s: Failed to read channel \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001251 return eERR_CHAN_READ;
1252}
1253
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301254/**
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301255 * Get the sap auto channel selection for soft AP.
1256 */
1257int qsap_get_sap_auto_channel_selection(s32 *pautochan)
1258{
1259 int sock;
1260 struct iwreq wrq;
1261 s8 interface[MAX_CONF_LINE_LEN];
1262 u32 len = MAX_CONF_LINE_LEN;
1263 s8 *pif;
1264 int ret;
1265 sap_auto_channel_info sap_autochan_info;
1266 s32 *pchan;
1267
1268 if(ENABLE != is_softap_enabled()) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301269 ALOGE("%s :is_softap_enabled() goto error \n", __func__);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301270 goto error;
1271 }
1272
1273 if(NULL == (pif = qsap_get_config_value(pconffile,
1274 &qsap_str[STR_INTERFACE], interface, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301275 ALOGD("%s :interface error \n", __func__);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301276 goto error;
1277 }
1278
1279 interface[len] = '\0';
1280
1281 sock = socket(AF_INET, SOCK_DGRAM, 0);
1282 if(sock < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301283 ALOGD("%s :socket error \n", __func__);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301284 goto error;
1285 }
1286
1287 *pautochan = 0;
1288
1289 memset(&sap_autochan_info, 0, sizeof(sap_autochan_info));
1290 memset(&wrq, 0, sizeof(wrq));
1291
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +05301292 strlcpy(wrq.ifr_name, pif, sizeof(wrq.ifr_name));
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301293 wrq.u.data.length = sizeof(s32);
1294 sap_autochan_info.subioctl = QCSAP_PARAM_GET_AUTO_CHANNEL;
1295 wrq.u.data.pointer = pautochan;
1296 memcpy(wrq.u.name, (char *)(&sap_autochan_info), sizeof(sap_autochan_info));
1297 wrq.u.data.flags = 0;
1298
1299 ret = ioctl(sock, QCSAP_IOCTL_GETPARAM, &wrq);
1300 if(ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301301 ALOGE("%s: ioctl failure \n",__func__);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301302 close(sock);
1303 goto error;
1304 }
1305
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301306 ALOGD("Recv len :%d \n", wrq.u.data.length);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301307 *pautochan = *(int *)(&wrq.u.name[0]);
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301308 ALOGD("Sap auto channel selection pautochan=%ld \n", *pautochan);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301309 close(sock);
1310 return eSUCCESS;
1311
1312error:
1313 *pautochan = 0;
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301314 ALOGE("%s: Failed to read sap auto channel selection\n", __func__);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301315 return eERR_GET_AUTO_CHAN;
1316}
1317
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301318
Hu Wang76d63aa2018-07-06 15:40:54 +08001319static int iftypeCallback(struct nl_msg* msg, void* arg)
1320{
1321 struct nlmsghdr* ret_hdr = nlmsg_hdr(msg);
1322 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
1323 int* type = arg;
1324
1325 struct genlmsghdr *gnlh = (struct genlmsghdr*) nlmsg_data(ret_hdr);
1326
1327 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1328 genlmsg_attrlen(gnlh, 0), NULL);
1329
1330 if (tb_msg[NL80211_ATTR_IFTYPE]) {
1331 *type = nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]);
1332
1333 }
1334 return NL_SKIP;
1335}
1336
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301337/**
1338 * Get the mode of operation.
1339 */
1340int qsap_get_mode(s32 *pmode)
1341{
Hu Wang76d63aa2018-07-06 15:40:54 +08001342 int ret = eERR_UNKNOWN;
1343 struct nl_sock* sk = NULL;
1344 int nl80211_id = -1;
1345 int if_type = -1;
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301346 s8 interface[MAX_CONF_LINE_LEN];
1347 u32 len = MAX_CONF_LINE_LEN;
1348 s8 *pif;
Hu Wang76d63aa2018-07-06 15:40:54 +08001349 struct nl_msg* msg = NULL;
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301350
Hu Wang76d63aa2018-07-06 15:40:54 +08001351 //get interface name
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301352 if(NULL == (pif = qsap_get_config_value(pconffile,
1353 &qsap_str[STR_INTERFACE], interface, &len))) {
1354 ALOGD("%s :interface error \n", __func__);
Hu Wang76d63aa2018-07-06 15:40:54 +08001355 goto nla_put_failure;
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301356 }
1357
1358 interface[len] = '\0';
1359
Hu Wang76d63aa2018-07-06 15:40:54 +08001360 //allocate socket
1361 sk = nl_socket_alloc();
1362
Srikanth Marepalli71d1ddb2018-08-23 19:15:57 +05301363 //return if socket allocation fails
1364 if(sk == NULL){
1365 ALOGE( "socket allocation failure");
1366 return ret;
1367 }
1368
Hu Wang76d63aa2018-07-06 15:40:54 +08001369 //connect to generic netlink
1370 if (genl_connect(sk)) {
1371 ALOGE( "Netlink socket Connection failure");
1372 ret = eERR_UNKNOWN;
1373 goto nla_put_failure;
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301374 }
1375
Hu Wang76d63aa2018-07-06 15:40:54 +08001376 //find the nl80211 driver ID
1377 nl80211_id = genl_ctrl_resolve(sk, "nl80211");
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301378
Hu Wang76d63aa2018-07-06 15:40:54 +08001379 //attach a callback
1380 nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM,
1381 iftypeCallback, &if_type);
1382
1383 //allocate a message
1384 msg = nlmsg_alloc();
1385
Srikanth Marepalli71d1ddb2018-08-23 19:15:57 +05301386 //return if message allocation fails
1387 if(msg == NULL){
1388 ALOGE( "message allocation failure");
1389 goto nla_put_failure;
1390 }
1391
Hu Wang76d63aa2018-07-06 15:40:54 +08001392 // setup the message
1393 genlmsg_put(msg, 0, 0, nl80211_id, 0, 0, NL80211_CMD_GET_INTERFACE, 0);
1394
1395 //add message attributes
1396 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(pif));
1397
1398 // Send the message
1399 ret = nl_send_auto_complete(sk, msg);
1400 if (ret < 0 ) {
1401 ALOGE( "nl_send_auto_complete failure");
1402 ret = eERR_UNKNOWN;
1403 goto nla_put_failure;
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301404 }
1405
Hu Wang76d63aa2018-07-06 15:40:54 +08001406 //block for message to return
1407 nl_recvmsgs_default(sk);
1408 *pmode = if_type;
1409 ALOGI("%s: (%s) NL80211 Get Mode = %d \n",__func__, pif, (int)*pmode);
1410 ret = eSUCCESS;
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301411
Hu Wang76d63aa2018-07-06 15:40:54 +08001412nla_put_failure:
1413 if (sk)
1414 nl_socket_free(sk);
1415 if (msg)
1416 nlmsg_free(msg);
1417 return ret;
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +05301418}
1419
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301420/**
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301421 * Set the channel Range for soft AP.
1422 */
1423int qsap_set_channel_range(s8 *buf)
1424{
1425 int sock;
1426 struct iwreq wrq;
1427 s8 interface[MAX_CONF_LINE_LEN];
1428 u32 len = MAX_CONF_LINE_LEN;
1429 s8 *pif;
1430 s8 *temp;
1431 int ret, i;
1432 sap_channel_info sap_chan_range;
1433 sta_channel_info sta_chan_range;
1434
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301435 ALOGE("buf :%s\n", buf);
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301436
1437 temp = buf;
1438 temp = strchr(buf, '=');
1439 if (NULL == temp) {
1440 goto error;
1441 }
1442 temp++;
1443
1444 if (NULL == (pif = qsap_get_config_value(pconffile,
1445 &qsap_str[STR_INTERFACE], interface, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301446 ALOGE("%s :interface error\n", __func__);
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301447 goto error;
1448 }
1449
1450 interface[len] = '\0';
1451
1452 sock = socket(AF_INET, SOCK_DGRAM, 0);
1453 if (sock < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301454 ALOGE("%s :socket error\n", __func__);
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301455 goto error;
1456 }
1457
1458 memset(&sap_chan_range, 0, sizeof(sap_chan_range));
1459 memset(&sta_chan_range, 0, sizeof(sta_chan_range));
1460 memset(&wrq, 0, sizeof(wrq));
1461
1462 if (ENABLE != is_softap_enabled()) {
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +05301463 strlcpy(wrq.ifr_name, "wlan0", sizeof(wrq.ifr_name));
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301464 sta_chan_range.subioctl = WE_SET_SAP_CHANNELS;
Shake M Subhaniff6440b2013-11-06 17:39:46 +05301465 ret = sscanf(temp, "%d %d %d", &(sta_chan_range.stastartchan),
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301466 &(sta_chan_range.staendchan), &(sta_chan_range.staband));
Shake M Subhaniff6440b2013-11-06 17:39:46 +05301467 if (3 != ret) {
1468 ALOGE("%s : sscanf is not successful\n", __func__);
1469 close(sock);
1470 goto error;
1471 }
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301472 memcpy(wrq.u.name, (char *)(&sta_chan_range), sizeof(sta_chan_range));
1473
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301474 ALOGE("%s :Softap is off,Send SET_CHANNEL_RANGE over sta interface\n",
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301475 __func__);
1476 ret = ioctl(sock, WLAN_PRIV_SET_THREE_INT_GET_NONE, &wrq);
1477 } else {
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +05301478 strlcpy(wrq.ifr_name, pif, sizeof(wrq.ifr_name));
Shake M Subhaniff6440b2013-11-06 17:39:46 +05301479 ret = sscanf(temp, "%d %d %d", &(sap_chan_range.startchan),
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301480 &(sap_chan_range.endchan), &(sap_chan_range.band));
Shake M Subhaniff6440b2013-11-06 17:39:46 +05301481 if (3 != ret) {
1482 ALOGE("%s : sscanf is not successful\n", __func__);
1483 close(sock);
1484 goto error;
1485 }
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301486 memcpy(wrq.u.name, (char *)(&sap_chan_range), sizeof(sap_chan_range));
1487
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301488 ALOGE("%s :SAP is on,Send SET_CHANNEL_RANGE over softap interface\n",
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301489 __func__);
1490 ret = ioctl(sock, QCSAP_IOCTL_SET_CHANNEL_RANGE, &wrq);
1491 }
1492
1493 if (ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301494 ALOGE("%s: ioctl failure\n", __func__);
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301495 close(sock);
1496 goto error;
1497 }
1498
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301499 ALOGE("Recv len :%d\n", wrq.u.data.length);
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301500
1501 close(sock);
1502 return eSUCCESS;
1503
1504error:
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301505 ALOGE("%s: Failed to set channel range\n", __func__);
Deepthi Gowri684d2f92012-05-23 23:28:16 +05301506 return eERR_SET_CHAN_RANGE;
1507}
1508
Raj Kushwahaae27f822010-11-14 17:47:11 -08001509int qsap_read_channel(s8 *pfile, struct Command *pcmd, s8 *presp, u32 *plen, s8 *pvar)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001510{
1511 s8 *pval;
1512 s32 chan;
1513 u32 len = *plen;
1514
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301515 if(eSUCCESS == qsap_get_operating_channel(&chan)) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001516 *plen = qsap_scnprintf(presp, len, "%s %s=%lu", SUCCESS, pcmd->name, chan);
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301517 ALOGD("presp :%s\n", presp);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301518 } else {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001519 *plen = qsap_scnprintf(presp, len, "%s", ERR_UNKNOWN);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301520 }
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001521
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301522 return eSUCCESS;
1523}
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001524
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301525int qsap_read_auto_channel(struct Command *pcmd, s8 *presp, u32 *plen)
1526{
1527 s8 *pval, *pautoval;
1528 s32 pautochan;
1529 u32 len = *plen;
1530 int autochan;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001531
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301532 ALOGE("%s :\n", __func__);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301533
1534 if (eSUCCESS == qsap_get_sap_auto_channel_selection(&pautochan)) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001535 *plen = qsap_scnprintf(presp, len, "%s autochannel=%lu", SUCCESS, pautochan);
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301536 ALOGE("presp :%s\n", presp);
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301537 } else {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001538 *plen = qsap_scnprintf(presp, len, "%s", ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001539 }
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301540
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001541 return eSUCCESS;
1542}
1543
1544static int qsap_mac_to_macstr(s8 *pmac, u32 slen, s8 *pmstr, u32 *plen)
1545{
1546 int len;
1547 int totlen = 0;
1548
1549 while((slen > 0) && (*plen > 0)) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001550 len = qsap_scnprintf(pmstr, *plen, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X ", (int)pmac[0], (int)pmac[1], (int)pmac[2],
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001551 (int)pmac[3], (int)pmac[4], (int)pmac[5]);
1552 pmac += 6;
1553 slen -= 6;
1554 *plen -= len;
1555 pmstr += len;
1556 totlen += len;
1557 }
1558
1559 if(totlen > 0) {
1560 *pmstr--;
1561 totlen--;
1562 }
1563 *pmstr = '\0';
1564 *plen = totlen;
1565
1566 return 0;
1567}
1568
1569#define MAX_STA_ALLOWED 8
1570void qsap_get_associated_sta_mac(s8 *presp, u32 *plen)
1571{
1572 int sock, ret;
1573 struct iwreq wrq;
1574 s8 interface[MAX_CONF_LINE_LEN];
1575 u32 len = MAX_CONF_LINE_LEN;
1576 s8 *pif;
1577 s8 *pbuf, *pout;
Ravi Joshi124fb552014-04-02 16:18:12 -07001578 u32 buflen;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001579 u32 recvLen;
1580 u32 tlen;
1581
Raj Kushwaha41027212010-10-13 00:11:12 -07001582 if(ENABLE != is_softap_enabled()) {
1583 goto error;
1584 }
1585
Raj Kushwahaae27f822010-11-14 17:47:11 -08001586 if(NULL == (pif = qsap_get_config_value(pconffile, &qsap_str[STR_INTERFACE], interface, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301587 ALOGE("%s :interface error \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001588 goto error;
1589 }
1590 interface[len] = '\0';
1591
1592 sock = socket(AF_INET, SOCK_DGRAM, 0);
1593 if(sock < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301594 ALOGE("%s :socket failure \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001595 goto error;
1596 }
1597
Ravi Joshi124fb552014-04-02 16:18:12 -07001598 /* response has length field + 6 bytes per STA */
1599 buflen = sizeof(u32) + (MAX_STA_ALLOWED * 6);
1600 pbuf = (s8 *)malloc(buflen);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001601 if(NULL == pbuf) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301602 ALOGE("%s :No memory \n", __func__);
santosh sajjan1a6aff92011-07-18 17:11:12 +05301603 close(sock);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001604 goto error;
1605 }
1606
1607
1608#define SIZE_OF_MAC_INT (6)
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +05301609 strlcpy(wrq.ifr_name, pif, sizeof(wrq.ifr_name));
Ravi Joshi124fb552014-04-02 16:18:12 -07001610 wrq.u.data.length = buflen;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001611 wrq.u.data.pointer = (void *)pbuf;
1612 wrq.u.data.flags = 0;
1613
1614 ret = ioctl(sock, QCSAP_IOCTL_ASSOC_STA_MACADDR, &wrq);
1615 if(ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301616 ALOGE("%s :ioctl failure \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001617 free(pbuf);
santosh sajjan1a6aff92011-07-18 17:11:12 +05301618 close(sock);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001619 goto error;
1620 }
1621
Ravi Joshi124fb552014-04-02 16:18:12 -07001622 recvLen = *(u32 *)(wrq.u.data.pointer);
1623 recvLen -= sizeof(u32);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001624
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001625 len = qsap_scnprintf(presp, *plen, "%s %s=", SUCCESS, cmd_list[eCMD_ASSOC_STA_MACS].name);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001626 pout = presp + len;
1627 tlen = *plen - len;
1628
Ravi Joshi124fb552014-04-02 16:18:12 -07001629 qsap_mac_to_macstr(pbuf+sizeof(u32), recvLen, pout, &tlen);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001630
1631 *plen = len + tlen;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001632
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001633 free(pbuf);
santosh sajjan1a6aff92011-07-18 17:11:12 +05301634 close(sock);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001635
1636 return;
1637error:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001638 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001639
1640 return;
1641}
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001642
Raj Kushwahaae27f822010-11-14 17:47:11 -08001643static void qsap_read_wep_key(s8 *pfile, struct Command *pcmd, s8 *presp, u32 *plen, s8 *var)
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001644{
1645 s8 *pwep;
1646 s8 *pkey;
1647
1648 if(eSUCCESS != qsap_read_cfg(pfile, pcmd, presp, plen, var, GET_COMMENTED_VALUE))
1649 return;
1650
1651 pwep = strchr(presp, '=');
1652 if(NULL == pwep)
1653 return;
1654 pwep++;
1655
1656 if(pwep[0] == '"') {
1657 pkey = pwep;
1658 pwep++;
1659
1660 while(*pwep != '\0') {
1661 *pkey = *pwep;
1662 pkey++;
1663 pwep++;
1664 }
1665 *pkey--;
1666 *pkey = '\0';
1667 *plen -= 2;
1668 }
1669
1670 return;
1671}
1672
Raj Kushwaha41027212010-10-13 00:11:12 -07001673void qsap_read_ap_stats(s8 *presp, u32 *plen)
1674{
1675 int sock, ret;
1676 struct iwreq wrq;
1677 s8 interface[MAX_CONF_LINE_LEN];
1678 u32 len = MAX_CONF_LINE_LEN;
1679 s8 *pif;
1680 s8 *pbuf, *pout;
Raj Kushwaha41027212010-10-13 00:11:12 -07001681 u32 tlen;
1682
1683 if(ENABLE != is_softap_enabled()) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001684 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_SOFTAP_NOT_STARTED);
Raj Kushwaha41027212010-10-13 00:11:12 -07001685 return;
1686 }
1687
Raj Kushwahaae27f822010-11-14 17:47:11 -08001688 if(NULL == (pif = qsap_get_config_value(pconffile, &qsap_str[STR_INTERFACE], interface, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301689 ALOGE("%s :interface error \n", __func__);
Raj Kushwaha41027212010-10-13 00:11:12 -07001690 goto error;
1691 }
1692 interface[len] = '\0';
1693
1694 sock = socket(AF_INET, SOCK_DGRAM, 0);
1695 if(sock < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301696 ALOGE("%s :socket failure \n", __func__);
Raj Kushwaha41027212010-10-13 00:11:12 -07001697 goto error;
1698 }
1699
1700 pbuf = (s8 *)malloc(MAX_RESP_LEN);
1701 if(NULL == pbuf) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301702 ALOGE("%s :No memory \n", __func__);
santosh sajjan1a6aff92011-07-18 17:11:12 +05301703 close(sock);
Raj Kushwaha41027212010-10-13 00:11:12 -07001704 goto error;
1705 }
1706
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +05301707 strlcpy(wrq.ifr_name, pif, sizeof(wrq.ifr_name));
Raj Kushwaha41027212010-10-13 00:11:12 -07001708 wrq.u.data.length = MAX_RESP_LEN;
1709 wrq.u.data.pointer = (void *)pbuf;
1710 wrq.u.data.flags = 0;
1711
1712 ret = ioctl(sock, QCSAP_IOCTL_AP_STATS, &wrq);
1713 if(ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301714 ALOGE("%s :ioctl failure \n", __func__);
Raj Kushwaha41027212010-10-13 00:11:12 -07001715 free(pbuf);
santosh sajjan1a6aff92011-07-18 17:11:12 +05301716 close(sock);
Raj Kushwaha41027212010-10-13 00:11:12 -07001717 goto error;
1718 }
1719
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001720 *plen = qsap_scnprintf(presp, *plen, "%s %s=%s", SUCCESS, cmd_list[eCMD_AP_STATISTICS].name, pbuf);
Raj Kushwaha41027212010-10-13 00:11:12 -07001721
1722 free(pbuf);
santosh sajjan1a6aff92011-07-18 17:11:12 +05301723 close(sock);
Raj Kushwaha41027212010-10-13 00:11:12 -07001724 return;
1725
1726error:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001727 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_UNKNOWN);
Raj Kushwaha41027212010-10-13 00:11:12 -07001728
1729 return;
1730}
1731
1732void qsap_read_autoshutoff(s8 *presp, u32 *plen)
1733{
1734 u32 tlen, time = 0;
1735 s8 *ptime;
1736
1737 tlen = *plen;
1738
Raj Kushwahaae27f822010-11-14 17:47:11 -08001739 if(NULL == (ptime = qsap_get_config_value(fIni, &qsap_str[STR_AP_AUTOSHUTOFF], presp, &tlen))) {
Raj Kushwaha41027212010-10-13 00:11:12 -07001740 /** unable to read the AP shutoff time */
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301741 ALOGE("%s :Failed to read AP shutoff time\n", __func__);
Raj Kushwaha41027212010-10-13 00:11:12 -07001742 }
1743 else {
1744 time = atoi(ptime);
1745 time = time / 60; /** Convert seconds to minutes */
1746 }
1747
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001748 *plen = qsap_scnprintf(presp, *plen, "success %s=%ld", cmd_list[eCMD_AP_AUTOSHUTOFF].name, time);
Raj Kushwaha41027212010-10-13 00:11:12 -07001749
1750 return;
1751}
1752
1753
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001754/**
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001755 * @brief
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001756 * Get the configuration information from the softAP configuration
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001757 * files
1758 * @param cNum [INPUT]
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001759 * @param presp [OUTPUT] presp The command output format :
1760 * On success,
1761 * success <cmd>=<value>
1762 * On failure,
1763 * failure <error message>
1764 * @param plen [IN-OUT] plen
1765 * [IN] The length of the buffer, presp
1766 * [OUT] The length of the response in the buffer, presp
1767 * @return void
1768**/
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001769static void qsap_get_from_config(esap_cmd_t cNum, s8 *presp, u32 *plen)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001770{
1771 u32 len;
1772 int status;
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001773 s8 * pval;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001774
1775 switch(cNum) {
1776 case eCMD_ENABLE_SOFTAP:
1777 status = is_softap_enabled();
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001778 *plen = qsap_scnprintf(presp, *plen, "%s %s=%d", SUCCESS, cmd_list[cNum].name, status);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001779 break;
1780
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001781 case eCMD_WPA_PAIRWISE:
1782 case eCMD_RSN_PAIRWISE:
1783 case eCMD_DEFAULT_KEY:
1784 case eCMD_PASSPHRASE:
1785 case eCMD_GTK_TIMEOUT:
Raj Kushwahaae27f822010-11-14 17:47:11 -08001786 qsap_read_cfg(pconffile, &cmd_list[cNum], presp, plen, NULL, GET_COMMENTED_VALUE);
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001787 break;
1788
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001789 case eCMD_SSID:
1790 case eCMD_BSSID:
1791 case eCMD_BCN_INTERVAL:
1792 case eCMD_DTIM_PERIOD:
1793 case eCMD_HW_MODE:
1794 case eCMD_AUTH_ALGS:
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001795 case eCMD_MAC_ACL:
1796 case eCMD_WPS_CONFIG_METHOD:
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001797 case eCMD_UUID:
1798 case eCMD_DEVICE_NAME:
1799 case eCMD_MANUFACTURER:
1800 case eCMD_MODEL_NAME:
1801 case eCMD_MODEL_NUMBER:
1802 case eCMD_SERIAL_NUMBER:
1803 case eCMD_DEVICE_TYPE:
1804 case eCMD_OS_VERSION:
1805 case eCMD_FRIENDLY_NAME:
1806 case eCMD_MANUFACTURER_URL:
1807 case eCMD_MODEL_DESC:
1808 case eCMD_MODEL_URL:
1809 case eCMD_UPC:
Raj Kushwahaae27f822010-11-14 17:47:11 -08001810 case eCMD_SDK_VERSION:
Santosh Sajjanc463f732011-12-22 18:24:56 +05301811 case eCMD_COUNTRY_CODE:
Raj Kushwahaae27f822010-11-14 17:47:11 -08001812 qsap_read_cfg(pconffile, &cmd_list[cNum], presp, plen, NULL, GET_ENABLED_ONLY);
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001813 break;
1814
1815 case eCMD_WEP_KEY0:
1816 case eCMD_WEP_KEY1:
1817 case eCMD_WEP_KEY2:
1818 case eCMD_WEP_KEY3:
Raj Kushwahaae27f822010-11-14 17:47:11 -08001819 qsap_read_wep_key(pconffile, &cmd_list[cNum], presp, plen, NULL);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001820 break;
1821
1822 case eCMD_CHAN:
Raj Kushwahaae27f822010-11-14 17:47:11 -08001823 qsap_read_channel(pconffile, &cmd_list[cNum], presp, plen, NULL);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001824 break;
1825
1826 case eCMD_FRAG_THRESHOLD:
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001827 case eCMD_REGULATORY_DOMAIN:
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001828 case eCMD_RTS_THRESHOLD:
Pradeep Reddy POTTETI5c1a3ab2016-01-07 20:01:40 +05301829 case eCMD_IEEE80211H:
Ashwini Sukhadev Patilcc163152015-09-09 20:34:28 +05301830 qsap_read_cfg(pconffile, &cmd_list[cNum], presp, plen, NULL, GET_ENABLED_ONLY);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001831 break;
1832
1833 case eCMD_ALLOW_LIST: /* fall through */
1834 case eCMD_DENY_LIST:
1835 qsap_get_mac_list(pconffile, cNum, presp, plen);
1836 break;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001837
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001838 case eCMD_SEC_MODE:
1839 qsap_read_security_mode(pconffile, presp, plen);
1840 break;
1841
1842 case eCMD_MAC_ADDR:
1843 if(eSUCCESS != qsap_read_mac_address(presp, plen)) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001844 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_NOT_SUPPORTED);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001845 }
1846 break;
1847
1848 case eCMD_WMM_STATE:
Ashwini Sukhadev Patilcc163152015-09-09 20:34:28 +05301849 qsap_read_cfg(pconffile, &cmd_list[cNum], presp, plen, NULL, GET_ENABLED_ONLY);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001850 break;
1851
1852 case eCMD_WPS_STATE:
1853 qsap_read_wps_state(presp, plen);
1854 break;
1855
1856 case eCMD_PROTECTION_FLAG:
Raj Kushwahaae27f822010-11-14 17:47:11 -08001857 qsap_read_cfg(fIni, &qsap_str[STR_PROT_FLAG_IN_INI], presp, plen, cmd_list[eCMD_PROTECTION_FLAG].name, GET_ENABLED_ONLY);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001858 break;
1859
1860 case eCMD_DATA_RATES:
Raj Kushwahaae27f822010-11-14 17:47:11 -08001861 qsap_read_cfg(fIni, &qsap_str[STR_DATA_RATE_IN_INI], presp, plen, cmd_list[eCMD_DATA_RATES].name, GET_ENABLED_ONLY);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001862 break;
1863
1864 case eCMD_ASSOC_STA_MACS:
1865 qsap_get_associated_sta_mac(presp, plen);
1866 break;
1867
1868 case eCMD_TX_POWER:
Raj Kushwahaae27f822010-11-14 17:47:11 -08001869 qsap_read_cfg(fIni, &qsap_str[STR_TX_POWER_IN_INI], presp, plen, cmd_list[eCMD_TX_POWER].name, GET_ENABLED_ONLY);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001870 break;
1871
1872 case eCMD_INTRA_BSS_FORWARD:
Deepthi Gowri6344a802012-01-12 17:11:18 +05301873 qsap_read_cfg(pconffile, &cmd_list[eCMD_INTRA_BSS_FORWARD], presp, plen, NULL, GET_ENABLED_ONLY);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001874 break;
1875
Raj Kushwaha41027212010-10-13 00:11:12 -07001876 case eCMD_AP_STATISTICS:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001877 qsap_read_ap_stats(presp, plen);
Raj Kushwaha41027212010-10-13 00:11:12 -07001878 break;
1879
1880 case eCMD_AP_AUTOSHUTOFF:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001881 qsap_read_autoshutoff(presp, plen);
Raj Kushwaha41027212010-10-13 00:11:12 -07001882 break;
1883
1884 case eCMD_AP_ENERGY_DETECT_TH:
Raj Kushwahaae27f822010-11-14 17:47:11 -08001885 qsap_read_cfg(fIni, &qsap_str[STR_AP_ENERGY_DETECT_TH], presp, plen, cmd_list[eCMD_AP_ENERGY_DETECT_TH].name, GET_ENABLED_ONLY);
Raj Kushwaha41027212010-10-13 00:11:12 -07001886 break;
Deepthi Gowri6ce57562012-06-27 01:18:15 +05301887 case eCMD_GET_AUTO_CHANNEL:
1888 qsap_read_auto_channel(&cmd_list[cNum],presp, plen);
1889 break;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001890 default:
1891 /** Error case */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001892 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_ARG);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001893 }
1894
1895 len = *plen-1;
1896
1897 /** Remove the space or tabs in the end of response */
1898 while(len) {
1899 if((presp[len] == ' ') || (presp[len] == '\t'))
1900 len--;
1901 else
1902 break;
1903 }
1904 presp[len+1] = '\0';
1905 *plen = len+1;
1906
1907 return;
1908}
1909
1910/**
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001911 * @brief
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001912 * Identify the command number corresponding to the input user command.
1913 * @param cName [INPUT] command name
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001914 * @return
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001915 * On success,
1916 * command number in the range 0 to (eCMD_INVALID-1)
1917 * On failure,
1918 * eCMD_INVALID
1919**/
1920static esap_cmd_t qsap_get_cmd_num(s8 *cName)
1921{
1922 s16 i, len;
1923
1924 for(i=0; i<eCMD_LAST; i++) {
Raj Kushwahaae27f822010-11-14 17:47:11 -08001925 len = strlen(cmd_list[i].name);
Hu Wang62ae34e2019-01-31 10:26:14 +08001926
Raj Kushwahaae27f822010-11-14 17:47:11 -08001927 if(!strncmp(cmd_list[i].name, cName, len)) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001928 if((cName[len] == '=') || (cName[len] == '\0'))
1929 return i;
1930 }
1931 }
1932 return eCMD_INVALID;
1933}
1934
1935/**
1936 * @brief
1937 * Handle the user requests of the form,
1938 * "get <cmd num> [<value1> ...]"
1939 * These commands are used to retreive the soft AP
1940 * configuration information
1941 *
Raj Kushwahaae27f822010-11-14 17:47:11 -08001942 * @param pcmd [IN] pointer to the structure, storing the command.
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001943 * @param presp [OUT] pointer to the buffer, to store the command response.
1944 * The command output format :
1945 * On success,
1946 * success <cmd>=<value>
1947 * On failure,
1948 * failure <error message>
1949 * @param plen [IN-OUT]
1950 * [IN] : Maximum length of the reponse buffer
1951 * [OUT]: Reponse length
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001952 * @return
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001953 * void
1954*/
1955static void qsap_handle_get_request(s8 *pcmd, s8 *presp, u32 *plen)
1956{
1957 esap_cmd_t cNum;
1958
1959 pcmd += strlen("get");
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001960
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001961 SKIP_BLANK_SPACE(pcmd);
1962
1963 cNum = qsap_get_cmd_num(pcmd);
1964
1965 if(cNum == eCMD_INVALID) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001966 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_PARAM);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001967 return;
1968 }
Raj Kushwahaae27f822010-11-14 17:47:11 -08001969
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001970 qsap_get_from_config(cNum, presp, plen);
1971
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001972 return;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001973}
1974
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001975static s16 is_valid_wep_key(s8 *pwep, s8 *pkey, s16 len)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001976{
1977 int weplen;
1978 s16 ret = TRUE;
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001979 int ascii = FALSE;
1980
1981 weplen = strlen(pwep);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08001982
1983 /** Remove the double quotes if any */
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001984 if((pwep[0] == '"') && (pwep[weplen-1] == '"')) {
1985 pwep[weplen-1] = '\0';
1986 pwep++;
1987 weplen -= 2;
1988 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001989
1990 /** The WEP key should be of length 5, 13 or 16 characters
1991 * or 10, 26, or 32 digits */
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001992 switch(weplen) {
1993 case WEP_64_KEY_ASCII:
1994 case WEP_128_KEY_ASCII:
1995 case WEP_152_KEY_ASCII:
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001996 weplen--;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07001997 while(weplen--) {
Raj Kushwahaba862bd2010-09-17 00:34:16 -07001998 if(0 == isascii(pwep[weplen])) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05301999 ALOGD("%c not ascii \n", pwep[weplen]);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002000 return FALSE;
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002001 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002002 }
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002003 ascii = TRUE;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002004 break;
2005
2006 case WEP_64_KEY_HEX:
2007 case WEP_128_KEY_HEX:
2008 case WEP_152_KEY_HEX:
2009 while(weplen--) {
2010 if(0 == isxdigit(pwep[weplen]))
2011 return FALSE;
2012 }
2013 break;
2014
2015 default:
2016 ret = FALSE;
2017 }
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002018
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002019 qsap_scnprintf(pkey, len, (ascii == TRUE) ? "\"%s\"" : "%s", pwep);
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002020
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002021 return ret;
2022}
2023
Raj Kushwahaae27f822010-11-14 17:47:11 -08002024s16 wifi_qsap_reset_to_default(s8 *pcfgfile, s8 *pdefault)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002025{
2026 FILE *fcfg, *ftmp;
2027 char buf[MAX_CONF_LINE_LEN];
2028 int status = eSUCCESS;
2029
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002030 fcfg = fopen(pdefault, "r");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002031
2032 if(NULL == fcfg) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302033 ALOGE("%s : unable to open file \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002034 return eERR_FILE_OPEN;
2035 }
2036
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002037 qsap_scnprintf(buf, sizeof(buf), "%s~", pcfgfile);
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002038
2039 ftmp = fopen(buf, "w+");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002040 if(NULL == ftmp) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302041 ALOGE("%s : unable to open file \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002042 fclose(fcfg);
2043 return eERR_FILE_OPEN;
2044 }
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002045
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002046 while(NULL != fgets(buf, MAX_CONF_LINE_LEN, fcfg)) {
2047 fprintf(ftmp, "%s", buf);
2048 }
2049
2050 fclose(fcfg);
2051 fclose(ftmp);
2052
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002053 qsap_scnprintf(buf, sizeof(buf), "%s~", pcfgfile);
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002054
2055 if(eERR_UNKNOWN == rename(buf, pcfgfile))
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002056 status = eERR_CONF_FILE;
2057
2058 /** Remove the temporary file. Dont care the return value */
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002059 unlink(buf);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002060
2061 return status;
2062}
2063
2064#define CTRL_IFACE_PATH_LEN (128)
Raj Kushwaha41027212010-10-13 00:11:12 -07002065
2066void qsap_del_ctrl_iface(void)
2067{
2068 u32 len;
2069 s8 dst_path[CTRL_IFACE_PATH_LEN], *pcif, *pif;
2070 s8 interface[64];
2071 s8 path[CTRL_IFACE_PATH_LEN + 64];
2072
2073 len = CTRL_IFACE_PATH_LEN;
2074
Raj Kushwahaae27f822010-11-14 17:47:11 -08002075 if(NULL == (pcif = qsap_get_config_value(pconffile, &qsap_str[STR_CTRL_INTERFACE], dst_path, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302076 ALOGE("%s :ctrl_iface path error \n", __func__);
Raj Kushwaha41027212010-10-13 00:11:12 -07002077 goto error;
2078 }
2079
2080 len = 64;
2081
Raj Kushwahaae27f822010-11-14 17:47:11 -08002082 if(NULL == (pif = qsap_get_config_value(pconffile, &qsap_str[STR_INTERFACE], interface, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302083 ALOGE("%s :interface error \n", __func__);
Raj Kushwaha41027212010-10-13 00:11:12 -07002084 goto error;
2085 }
2086
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002087 if ((int)sizeof(path) <= snprintf(path, sizeof(path), "%s/%s", pcif, pif)) {
2088 ALOGE("Iface path : truncating error, %s \n", path);
Raj Kushwaha41027212010-10-13 00:11:12 -07002089 goto error;
2090 }
2091
2092 unlink(path);
2093
2094error:
2095 return;
2096}
2097
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002098static int qsap_send_cmd_to_hostapd(s8 *pcmd)
2099{
2100 int sock;
2101 struct sockaddr_un cli;
2102 struct sockaddr_un ser;
2103 struct timeval timeout;
2104 int ret = eERR_SEND_TO_HOSTAPD;
2105 u32 len;
2106 fd_set read;
2107 s8 dst_path[CTRL_IFACE_PATH_LEN], *pcif, *pif;
2108 s8 interface[64];
2109 s8 *ptr;
2110 u32 retry_cnt = 3;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002111 size_t ptr_size;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002112
2113 len = CTRL_IFACE_PATH_LEN;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002114 ptr_size = (sizeof(ser.sun_path) < CTRL_IFACE_PATH_LEN)?
2115 CTRL_IFACE_PATH_LEN : sizeof(ser.sun_path);
2116 ptr = malloc(ptr_size);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002117 if(NULL == ptr) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302118 ALOGE("%s :No memory \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002119 return ret;
2120 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002121
Raj Kushwahaae27f822010-11-14 17:47:11 -08002122 if(NULL == (pcif = qsap_get_config_value(pconffile, &qsap_str[STR_CTRL_INTERFACE], dst_path, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302123 ALOGE("%s :ctrl_iface path error \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002124 goto error;
2125 }
2126
2127 len = 64;
2128
Raj Kushwahaae27f822010-11-14 17:47:11 -08002129 if(NULL == (pif = qsap_get_config_value(pconffile, &qsap_str[STR_INTERFACE], interface, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302130 ALOGE("%s :interface error \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002131 goto error;
2132 }
2133
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002134 if ((int)sizeof(ser.sun_path) <= snprintf(ptr, sizeof(ser.sun_path), "%s/%s", pcif, pif)) {
2135 /* the sun_path is truncated. */
2136 ALOGE("Iface path : truncating error, %s \n", ptr);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002137 goto error;
2138 }
2139
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302140 ALOGD("Connect to :%s\n", ptr);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002141
2142 sock = socket(PF_UNIX, SOCK_DGRAM, 0);
2143 if(sock < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302144 ALOGE("%s :Socket error \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002145 goto error;
2146 }
2147
2148 cli.sun_family = AF_UNIX;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002149 qsap_scnprintf(cli.sun_path, sizeof(cli.sun_path), SDK_CTRL_IF);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002150
2151 ret = bind(sock, (struct sockaddr *)&cli, sizeof(cli));
2152
2153 if(ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302154 ALOGE("Bind Failure\n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002155 goto close_ret;
2156 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002157
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002158 ser.sun_family = AF_UNIX;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002159 qsap_scnprintf(ser.sun_path, sizeof(ser.sun_path), "%s", ptr);
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302160 ALOGD("Connect to: %s,(%d)\n", ser.sun_path, sock);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002161
2162 ret = connect(sock, (struct sockaddr *)&ser, sizeof(ser));
2163 if(ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302164 ALOGE("Connect Failure...\n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002165 goto close_ret;
2166 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002167
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002168 ret = send(sock, pcmd, strlen(pcmd), 0);
2169 if(ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302170 ALOGE("Unable to send cmd to hostapd \n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002171 goto close_ret;
2172 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002173 /* reset the ptr buffer size for recv */
2174 len = ptr_size;
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002175
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002176#define HOSTAPD_RECV_TIMEOUT (2)
2177 while(1) {
2178 timeout.tv_sec = HOSTAPD_RECV_TIMEOUT;
2179 timeout.tv_usec = 0;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002180
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002181 FD_ZERO(&read);
2182 FD_SET(sock, &read);
2183
2184 ret = select(sock+1, &read, NULL, NULL, &timeout);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002185
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002186 if(FD_ISSET(sock, &read)) {
2187
2188 ret = recv(sock, ptr, len, 0);
2189
2190 if(ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302191 ALOGE("%s: recv() failed \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002192 goto close_ret;
2193 }
2194
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002195 if ((u32)ret >= len)
2196 ptr[len-1] = 0;
2197 else
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002198 ptr[ret] = 0;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002199
2200 if((ret > 0) && (ptr[0] == '<')) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302201 ALOGE("Not the expected response...\n: %s", ptr);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002202 retry_cnt--;
2203 if(retry_cnt)
2204 continue;
2205 break;
2206 }
2207
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002208 if(!strncmp(ptr, "FAIL", 4)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302209 ALOGE("Command failed in hostapd \n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002210 goto close_ret;
2211 }
Raj Kushwaha13eb75f2011-03-12 10:21:45 -08002212 else {
2213 break;
2214 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002215 }
2216 else {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302217 ALOGE("%s: Select failed \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002218 goto close_ret;
Raj Kushwaha13eb75f2011-03-12 10:21:45 -08002219 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002220 }
2221
2222 ret = eSUCCESS;
2223
2224close_ret:
2225 close(sock);
2226
2227error:
2228 free(ptr);
2229 unlink(SDK_CTRL_IF);
2230 return ret;
2231}
2232
2233static void qsap_update_wps_config(s8 *pVal, s8 *presp, u32 *plen)
2234{
2235 u32 tlen = *plen;
2236 s32 status;
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002237 s8 pwps_state[MAX_INT_STR+1];
2238 s32 i;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002239
2240 /* Enable/disable the following in hostapd.conf
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002241 * 1. Update the wps_state
2242 * 2. Set eap_server=1
2243 * 3. Update UPnP related variables
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002244 */
2245 status = atoi(pVal);
2246
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002247 qsap_scnprintf(pwps_state, sizeof(pwps_state), "%d", (status == ENABLE) ? WPS_STATE_ENABLE : WPS_STATE_DISABLE);
2248
Santosh Sajjan47e3a842011-12-10 21:11:12 +05302249 qsap_write_cfg(pconffile, &cmd_list[eCMD_WPS_STATE], pwps_state, presp, &tlen, HOSTAPD_CONF_QCOM_FILE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002250
Raj Kushwahaae27f822010-11-14 17:47:11 -08002251 if(eERR_UNKNOWN == qsap_change_cfg(pconffile, &cmd_list[eCMD_WPS_STATE], status)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302252 ALOGE("%s: Failed to enable %s\n", __func__, cmd_list[eCMD_WPS_STATE].name);
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002253 goto error;
2254 }
2255
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002256 qsap_scnprintf(pwps_state, sizeof(pwps_state), "%d", ENABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002257
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002258 /** update the eap_server=1 */
Santosh Sajjan47e3a842011-12-10 21:11:12 +05302259 qsap_write_cfg(pconffile, &qsap_str[STR_EAP_SERVER], pwps_state, presp, plen, HOSTAPD_CONF_QCOM_FILE);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002260
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002261 for(i=eCMD_UUID; i<=eCMD_UPC; i++) {
Raj Kushwahaae27f822010-11-14 17:47:11 -08002262 if(eERR_UNKNOWN == qsap_change_cfg(pconffile, &cmd_list[i], status)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302263 ALOGE("%s: failed to set %s\n", __func__, cmd_list[i].name);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002264 goto error;
2265 }
2266 }
2267
2268 return;
2269error:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002270 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002271
2272 return;
2273}
2274
2275static void qsap_config_wps_method(s8 *pVal, s8 *presp, u32 *plen)
2276{
2277 s8 buf[64];
2278 s8 *ptr;
2279 int i;
2280 s32 value;
2281
2282 /** INPUT : <0/1> <PIN> */
2283 /** PBC method : WPS_PBC */
2284 /** PIN method : WPS_PIN any <key> */
2285 ptr = pVal;
2286 i = 0;
2287
2288 while((*ptr != '\0') && (*ptr != ' ')) {
2289 buf[i] = *ptr;
2290 ptr++;
2291 i++;
2292 }
2293
2294 buf[i] = '\0';
2295
2296 /** Identify the WPS method */
2297 value = atoi(buf);
2298 if(TRUE != IS_VALID_WPS_CONFIG(value)) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002299 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_PARAM);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002300 return;
2301 }
2302
2303 SKIP_BLANK_SPACE(ptr);
2304
2305 if( (value == WPS_CONFIG_PIN) && (*ptr == '\0') ){
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302306 ALOGE("%s :Invalid command \n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002307 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_PARAM);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002308 return;
2309 }
2310
2311 if(value == WPS_CONFIG_PBC)
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002312 qsap_scnprintf(buf, sizeof(buf), "WPS_PBC");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002313 else {
2314 if(strlen(ptr) < WPS_KEY_LEN) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302315 ALOGD("%s :Invalid WPS key length\n", __func__);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002316 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_PARAM);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002317 return;
2318 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002319 qsap_scnprintf(buf, sizeof(buf), "WPS_PIN any %s", ptr);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002320 }
2321
2322 value = qsap_send_cmd_to_hostapd(buf);
2323
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002324 *plen = qsap_scnprintf(presp, *plen, "%s", (value == eSUCCESS) ? SUCCESS: ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002325
2326 return;
2327}
2328
2329
2330s32 atoh(u8 *str)
2331{
2332 u32 val = 0;
2333 u32 pos = 0;
2334 s32 len = strlen((char *)str) - 1;
2335
2336 while(len >= 0) {
2337 switch(str[len]) {
2338
2339 case '0' ... '9':
2340 val += (str[len] - '0') << pos;
2341 break;
2342
2343 case 'a' ... 'f':
2344 val += (str[len] - 'a' + 10) << pos;
2345 break;
2346
2347 case 'A'... 'F':
2348 val += (str[len] - 'A' + 10) << pos;
2349 break;
2350 }
2351 len--;
2352 pos += 4;
2353 }
2354
2355 return val;
2356}
2357
2358int qsap_get_mac_in_bytes(char *psmac, char *pbmac)
2359{
2360 int val;
2361 u8 str[3];
2362 u32 i;
2363
2364 str[2] = '\0';
2365
2366 if(FALSE == isValid_MAC_address(psmac)) {
2367 return FALSE;
2368 }
2369
2370 for(i=0; i<strlen(psmac); i++) {
2371 if(psmac[i] == ':')
2372 continue;
2373
2374 str[0] = psmac[i];
2375 str[1] = psmac[i+1];
2376 val = atoh(str);
2377 *pbmac = val;
2378 pbmac++;
2379 i += 2;
2380 }
2381 *pbmac = 0;
2382
2383 return TRUE;
2384}
2385
2386void qsap_disassociate_sta(s8 *pVal, s8 *presp, u32 *plen)
2387{
2388 int sock, ret = eERR_UNKNOWN;
2389 struct iwreq wrq;
2390 s8 pbuf[MAX_CONF_LINE_LEN];
2391 u32 len = MAX_CONF_LINE_LEN;
2392 s8 *pif;
2393
Raj Kushwaha41027212010-10-13 00:11:12 -07002394 if(ENABLE != is_softap_enabled()) {
2395 goto end;
2396 }
2397
Raj Kushwahaae27f822010-11-14 17:47:11 -08002398 if(NULL == (pif = qsap_get_config_value(pconffile, &qsap_str[STR_INTERFACE], pbuf, &len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302399 ALOGE("%s :interface error \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002400 goto end;
2401 }
2402
2403 pbuf[len] = '\0';
2404
2405 sock = socket(AF_INET, SOCK_DGRAM, 0);
2406 if(sock < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302407 ALOGE("%s: socket failure \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002408 goto end;
2409 }
2410
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +05302411 strlcpy(wrq.ifr_name, pif, sizeof(wrq.ifr_name));
Deepthi Gowri81a8a732013-02-26 09:06:54 +05302412
2413 if (TRUE != qsap_get_mac_in_bytes(pVal, (char *) &wrq.u)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302414 ALOGE("%s: Invalid input \n", __func__);
santosh sajjan1a6aff92011-07-18 17:11:12 +05302415 close(sock);
Deepthi Gowri81a8a732013-02-26 09:06:54 +05302416 goto end;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002417 }
2418
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002419 ret = ioctl(sock, QCSAP_IOCTL_DISASSOC_STA, &wrq);
2420 if(ret < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302421 ALOGE("%s: ioctl failure \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002422 }
santosh sajjan1a6aff92011-07-18 17:11:12 +05302423 close(sock);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002424
2425end:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002426 *plen = qsap_scnprintf(presp, *plen, "%s", (ret == eSUCCESS) ? SUCCESS : ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002427
2428 return;
2429}
2430
2431static int qsap_set_channel(s32 channel, s8 *tbuf, u32 *tlen)
2432{
2433 u32 ulen;
2434 s8 *pcfgval;
2435 s8 schan[MAX_INT_STR+1];
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002436 s8 *pcfg = pconffile;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002437
2438 ulen = *tlen;
2439
Purushottam Kushwaha168beeb2018-05-21 18:19:46 +05302440 /* Do not worry about hw_mode if intention is to use ACS (channel=0) */
2441 if (channel == 0)
2442 goto end;
2443
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002444 /** Read the current operating mode */
Raj Kushwahaae27f822010-11-14 17:47:11 -08002445 if(NULL == (pcfgval = qsap_get_config_value(pconffile, &cmd_list[eCMD_HW_MODE], tbuf, &ulen))) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002446 return eERR_UNKNOWN;
2447 }
2448
Santosh Sajjanc463f732011-12-22 18:24:56 +05302449 /** If the operating mode is 'A' and the channel to be set is in between 1 and 14
2450 * then change the operating mode to 'G' mode */
2451 if((!strcmp(hw_mode[HW_MODE_A], pcfgval)) && (channel <=14)) {
2452 /** Change the operating mode to 'G' */
2453 ulen = *tlen;
2454 if(eSUCCESS != qsap_write_cfg(pcfg, &cmd_list[eCMD_HW_MODE], hw_mode[HW_MODE_G], tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302455 ALOGE("%s :Unable to update the operating mode \n", __func__);
Santosh Sajjanc463f732011-12-22 18:24:56 +05302456 return eERR_UNKNOWN;
2457 }
2458 }
2459
Santosh Sajjan11d59f42012-07-16 12:29:47 +05302460 /** If the operating mode is NOT 'B' and the channel to be set is 14
Santosh Sajjanc463f732011-12-22 18:24:56 +05302461 * then change the operating mode to 'B' mode */
Santosh Sajjan11d59f42012-07-16 12:29:47 +05302462 if(strcmp(hw_mode[HW_MODE_B], pcfgval) && (channel == 14)) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002463 /** Change the operating mode to 'B' */
2464 ulen = *tlen;
Santosh Sajjan47e3a842011-12-10 21:11:12 +05302465 if(eSUCCESS != qsap_write_cfg(pcfg, &cmd_list[eCMD_HW_MODE], hw_mode[HW_MODE_B], tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302466 ALOGE("%s :Unable to update the operating mode \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002467 return eERR_UNKNOWN;
2468 }
Santosh Sajjanc463f732011-12-22 18:24:56 +05302469 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002470
Santosh Sajjanc463f732011-12-22 18:24:56 +05302471 if(channel > 14) {
2472 /** Change the operating mode to 'A' */
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002473 ulen = *tlen;
Santosh Sajjanc463f732011-12-22 18:24:56 +05302474 if(eSUCCESS != qsap_write_cfg(pcfg, &cmd_list[eCMD_HW_MODE], hw_mode[HW_MODE_A], tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302475 ALOGE("%s :Unable to update the operating mode \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002476 return eERR_UNKNOWN;
2477 }
2478 }
2479
Purushottam Kushwaha168beeb2018-05-21 18:19:46 +05302480end:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002481 qsap_scnprintf(schan, sizeof(schan), "%ld", channel);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002482
Santosh Sajjan47e3a842011-12-10 21:11:12 +05302483 return qsap_write_cfg(pcfg, &cmd_list[eCMD_CHAN], schan, tbuf, tlen, HOSTAPD_CONF_QCOM_FILE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002484}
2485
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002486static int qsap_set_operating_mode(s32 mode, s8 *pmode, int pmode_len, s8 *tbuf, u32 *tlen)
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002487{
2488 u32 ulen;
2489 s8 *pcfgval;
2490 s32 channel;
2491 s8 sconf[MAX_INT_STR+1];
2492 s8 *pcfg = pconffile;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002493 s32 rate_idx;
Santosh Sajjanc463f732011-12-22 18:24:56 +05302494 s8 ieee11n_enable[] = "1";
2495 s8 ieee11n_disable[] = "0";
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002496
2497 ulen = *tlen;
2498
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002499 /** Update the operating mode */
Santosh Sajjanc463f732011-12-22 18:24:56 +05302500 qsap_change_cfg(pcfg, &cmd_list[eCMD_BASIC_RATES],DISABLE);
2501 qsap_change_cfg(pcfg, &cmd_list[eCMD_REQUIRE_HT],DISABLE);
2502 qsap_write_cfg(pcfg, &cmd_list[eCMD_IEEE80211N],ieee11n_disable, tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE);
2503 switch(mode)
2504 {
2505 case HW_MODE_G_ONLY:
2506 qsap_change_cfg(pcfg, &cmd_list[eCMD_BASIC_RATES],ENABLE);
2507 break;
2508 case HW_MODE_N_ONLY:
2509 qsap_change_cfg(pcfg, &cmd_list[eCMD_REQUIRE_HT],ENABLE);
2510 /* fall through */
2511 case HW_MODE_N:
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05302512 case HW_MODE_G:
Santosh Sajjanc463f732011-12-22 18:24:56 +05302513 case HW_MODE_A:
Purushottam Kushwaha2ef0af22018-05-31 13:32:10 +05302514 case HW_MODE_ANY:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002515 ulen = *tlen;
Santosh Sajjanc463f732011-12-22 18:24:56 +05302516 qsap_write_cfg(pcfg, &cmd_list[eCMD_IEEE80211N],ieee11n_enable, tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE);
2517 break;
2518 case HW_MODE_B:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002519 ulen = *tlen;
Santosh Sajjanc463f732011-12-22 18:24:56 +05302520 qsap_write_cfg(pcfg, &cmd_list[eCMD_IEEE80211N],ieee11n_disable, tbuf, &ulen, HOSTAPD_CONF_QCOM_FILE);
2521 break;
Dedy Lansky59c014f2019-08-08 09:58:36 +03002522 case HW_MODE_AD:
2523 /** For 802.11ad, disable the 802.11 HT */
2524 qsap_change_cfg(pcfg, &cmd_list[eCMD_HT_CAPAB], DISABLE);
2525 break;
Santosh Sajjanc463f732011-12-22 18:24:56 +05302526 }
2527 if(mode == HW_MODE_G_ONLY || mode == HW_MODE_N_ONLY || mode == HW_MODE_N ) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002528 qsap_scnprintf(pmode, pmode_len, "%s",hw_mode[HW_MODE_G]);
Santosh Sajjanc463f732011-12-22 18:24:56 +05302529 }
Santosh Sajjan47e3a842011-12-10 21:11:12 +05302530 return qsap_write_cfg(pcfg, &cmd_list[eCMD_HW_MODE], pmode, tbuf, tlen, HOSTAPD_CONF_QCOM_FILE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002531}
2532
2533static int qsap_set_data_rate(s32 drate_idx, s8 *presp, u32 *plen)
2534{
2535 u32 ulen;
2536 s8 *pmode;
2537 s8 sconf[MAX_INT_STR+1];
2538 int ret = eERR_UNKNOWN;
2539
2540 if(TRUE != IS_VALID_DATA_RATE_IDX(drate_idx)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302541 ALOGE("%s :Invalid rate index \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002542 goto end;
2543 }
2544
2545 ulen = *plen;
2546 /** Read the current operating mode */
Raj Kushwahaae27f822010-11-14 17:47:11 -08002547 if(NULL == (pmode = qsap_get_config_value(pconffile, &cmd_list[eCMD_HW_MODE], presp, &ulen))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302548 ALOGE("%s :Unable to read mode \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002549 goto end;
2550 }
2551
2552 /** Validate the rate index against the current operating mode */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002553 if(((!strcmp(pmode, hw_mode[HW_MODE_B])) && (drate_idx > B_MODE_MAX_DATA_RATE_IDX)) ||
2554 ((!strcmp(pmode, hw_mode[HW_MODE_G]) || (!strcmp(pmode, hw_mode[HW_MODE_G_ONLY]))) &&
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002555 (drate_idx > G_ONLY_MODE_MAX_DATA_RATE_IDX))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302556 ALOGE("%s :Invalid rate index \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002557 goto end;
2558 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002559
2560 qsap_scnprintf(sconf, sizeof(sconf), "%ld", drate_idx);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002561
2562 /** Update the rate index in the configuration */
Raj Kushwahaae27f822010-11-14 17:47:11 -08002563 return qsap_write_cfg(fIni, &qsap_str[STR_DATA_RATE_IN_INI], sconf, presp, plen, INI_CONF_FILE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002564
2565end:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002566 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002567
2568 return ret;
2569}
2570
2571/**
2572 * @brief
2573 * Handle the user requests of the form,
2574 * "set <cmd num> <value1> ..."
2575 * These commands are used to update the soft AP
2576 * configuration information
2577 *
2578 * @param pcmd [IN] pointer to the string, storing the command.
2579 * @param presp [OUT] pointer to the buffer, to store the command response.
2580 * The command output format :
2581 * On success,
2582 * success
2583 * On failure,
2584 * failure <error message>
2585 * @param plen [IN-OUT]
2586 * [IN]: Maximum length of the reponse buffer
2587 * [OUT]: Reponse length
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002588 * @return
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002589 * void
2590*/
2591static void qsap_handle_set_request(s8 *pcmd, s8 *presp, u32 *plen)
2592{
2593 esap_cmd_t cNum;
2594 esap_str_t sNum = STR_DENY_MAC_FILE;
2595 s8 *pVal, *pfile;
2596 s8 filename[MAX_FILE_PATH_LEN];
2597 u32 ulen;
2598 s32 status;
2599 s32 value;
Santosh Sajjan47e3a842011-12-10 21:11:12 +05302600 s16 ini = HOSTAPD_CONF_QCOM_FILE;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002601 s8 *pcfg = pconffile;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002602
2603 pcmd += strlen("set");
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002604
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002605 SKIP_BLANK_SPACE(pcmd);
2606
Ajit Vaishyaa21d2652017-07-04 21:32:27 +05302607 if(!(strncmp(pcmd, Conf_req[CONF_2g], strlen(Conf_req[CONF_2g])))) {
2608 pcmd += strlen(Conf_req[CONF_2g]);
2609 SKIP_BLANK_SPACE(pcmd);
2610 } else if (!(strncmp(pcmd, Conf_req[CONF_5g], strlen(Conf_req[CONF_5g])))) {
2611 pcmd += strlen(Conf_req[CONF_5g]);
2612 SKIP_BLANK_SPACE(pcmd);
Hu Wangd8555002018-12-06 18:13:00 +08002613 } else if (!(strncmp(pcmd, Conf_req[CONF_owe], strlen(Conf_req[CONF_owe])))) {
2614 pcmd += strlen(Conf_req[CONF_owe]);
2615 SKIP_BLANK_SPACE(pcmd);
Dedy Lanskya2dd08f2019-11-10 13:58:58 +02002616 } else if (!(strncmp(pcmd, Conf_req[CONF_60g], strlen(Conf_req[CONF_60g])))) {
2617 pcmd += strlen(Conf_req[CONF_60g]);
2618 SKIP_BLANK_SPACE(pcmd);
Ajit Vaishyaa21d2652017-07-04 21:32:27 +05302619 } else {
2620 // DO NOTHING
2621 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002622 cNum = qsap_get_cmd_num(pcmd);
2623 if(cNum == eCMD_INVALID) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002624 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_ARG);
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302625 ALOGE("Invalid command number :%d\n", cNum);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002626 return;
2627 }
Raj Kushwahaae27f822010-11-14 17:47:11 -08002628 pVal = pcmd + strlen(cmd_list[cNum].name);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002629 if( (cNum != eCMD_COMMIT) &&
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002630 (cNum != eCMD_RESET_TO_DEFAULT) &&
Abhishek Srivastava80064982017-08-03 19:05:17 +05302631 ((*pVal != '=') || (((eCMD_PASSPHRASE != cNum)) && (strlen(pVal) < 2)))) {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002632 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_ARG);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002633 return;
2634 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002635
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002636 pVal++;
2637
2638 if((cNum != eCMD_COMMIT) && (cNum != eCMD_RESET_TO_DEFAULT)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302639 ALOGE("Cmd: %s Argument :%s \n", cmd_list[cNum].name, pVal);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002640 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002641 switch(cNum) {
2642 case eCMD_ADD_TO_ALLOW:
2643 case eCMD_REMOVE_FROM_ALLOW:
2644 sNum = STR_ACCEPT_MAC_FILE;
2645 /* fall through */
2646
2647 case eCMD_ADD_TO_DENY:
2648 case eCMD_REMOVE_FROM_DENY:
2649 ulen = MAX_FILE_PATH_LEN;
Raj Kushwahaae27f822010-11-14 17:47:11 -08002650 if(NULL != (pfile = qsap_get_allow_deny_file_name(pconffile, &qsap_str[sNum], filename, &ulen))) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002651 qsap_update_mac_list(pfile, cNum, pVal, presp, plen);
2652 }
2653 else {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002654 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_RES_UNAVAILABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002655 }
2656 return;
2657
2658 case eCMD_SEC_MODE:
2659 value = atoi(pVal);
2660 if(FALSE == IS_VALID_SEC_MODE(value))
2661 goto error;
2662 /** Write back the integer value. This is to avoid values like 01, 001, 0001
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002663 * being written to the configuration.
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002664 */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002665 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002666 qsap_set_security_mode(pconffile, value, presp, plen);
2667 return;
2668
2669 case eCMD_MAC_ACL:
2670 value = atoi(pVal);
2671 if(FALSE == IS_VALID_MAC_ACL(value))
2672 goto error;
Sameer Thalappilcaf87922012-01-30 16:56:29 -08002673
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002674 /** Write back the integer value. This is to avoid values like 01, 001, 0001
2675 * being written to the configuration
2676 */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002677 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Sameer Thalappilcaf87922012-01-30 16:56:29 -08002678
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002679 if(ACL_ALLOW_LIST == value) {
2680 value = ENABLE;
2681 status = DISABLE;
2682 }
Sameer Thalappilcaf87922012-01-30 16:56:29 -08002683 else if(ACL_DENY_LIST == value){
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002684 value = DISABLE;
2685 status = ENABLE;
2686 }
Sameer Thalappilcaf87922012-01-30 16:56:29 -08002687 else {
2688 // must be ACL_ALLOW_AND_DENY_LIST
2689 value = ENABLE;
2690 status = ENABLE;
2691 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002692
Raj Kushwahaae27f822010-11-14 17:47:11 -08002693 if(eERR_UNKNOWN != qsap_change_cfg(pconffile, &qsap_str[STR_ACCEPT_MAC_FILE], value)) {
2694 if(eERR_UNKNOWN != qsap_change_cfg(pconffile, &qsap_str[STR_DENY_MAC_FILE], status))
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002695 {
Santosh Sajjan47e3a842011-12-10 21:11:12 +05302696 qsap_write_cfg(pconffile, &cmd_list[cNum], pVal, presp, plen, HOSTAPD_CONF_QCOM_FILE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002697 }
2698 else {
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002699 goto error;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002700 }
2701 }
2702 else {
2703 goto error;
2704 }
2705 return;
2706
2707 case eCMD_COMMIT:
Santosh Sajjan47e3a842011-12-10 21:11:12 +05302708#if 0 // COMMIT is not required currently for ICS framework
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002709 if ( gIniUpdated ) {
2710 status = wifi_qsap_reload_softap();
2711 gIniUpdated = 0;
2712 }
2713 else {
2714 status = commit();
2715 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002716 *plen = qsap_scnprintf(presp, *plen, "%s", (status == eSUCCESS)? SUCCESS : ERR_UNKNOWN);
Santosh Sajjan47e3a842011-12-10 21:11:12 +05302717#endif
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002718 *plen = qsap_scnprintf(presp, *plen, "%s", SUCCESS);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002719 return;
2720
2721 case eCMD_ENABLE_SOFTAP:
2722 value = atoi(pVal);
2723
2724 if(TRUE != IS_VALID_SOFTAP_ENABLE(value))
2725 goto error;
2726
2727 if ( *pVal == '0' ) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002728 status = wifi_qsap_unload_driver();
2729 }
2730 else {
2731 status = wifi_qsap_load_driver();
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002732 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002733 *plen = qsap_scnprintf(presp, *plen, "%s", (status==eSUCCESS) ? SUCCESS : "failure Could not enable softap");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002734 return;
Dedy Lansky350c3532016-05-16 11:54:10 +03002735
2736 case eCMD_ENABLE_WIGIG_SOFTAP:
2737 value = atoi(pVal);
2738
2739 if (TRUE != IS_VALID_SOFTAP_ENABLE(value))
2740 goto error;
2741
2742 if ( *pVal == '0' ) {
2743 status = wifi_qsap_stop_wigig_softap();
2744 }
2745 else {
2746 status = wifi_qsap_start_wigig_softap();
2747 }
2748 *plen = qsap_scnprintf(presp, *plen, "%s", (status==eSUCCESS) ? SUCCESS : "failure Could not enable Wigig softap");
2749 return;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002750 case eCMD_SSID:
2751 value = strlen(pVal);
2752 if(SSD_MAX_LEN < value)
2753 goto error;
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05302754 /* Disable ssid2 while setting ssid */
2755 qsap_change_cfg(pcfg, &cmd_list[eCMD_SSID2], DISABLE);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002756 break;
2757
Changzhi Dengfddc6be2015-05-21 15:47:07 +08002758 case eCMD_SET_MAX_CLIENTS:
2759 value = strlen(pVal);
2760 break;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002761 case eCMD_BSSID:
2762 value = atoi(pVal);
2763 if(FALSE == IS_VALID_BSSID(value))
2764 goto error;
2765 /** Write back the integer value. This is to avoid values like 01, 001, 0001
2766 * being written to the configuration
2767 */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002768 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002769 break;
2770 case eCMD_PASSPHRASE:
2771 value = strlen(pVal);
2772 if(FALSE == IS_VALID_PASSPHRASE_LEN(value))
2773 goto error;
2774 break;
2775
2776 case eCMD_CHAN:
2777 value = atoi(pVal);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002778
2779 ulen = MAX_FILE_PATH_LEN;
2780 value = qsap_set_channel(value, filename, &ulen);
2781
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002782 *plen = qsap_scnprintf(presp, *plen, "%s", (value == eSUCCESS) ? SUCCESS : ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002783 return;
2784
2785 case eCMD_BCN_INTERVAL:
2786 value = atoi(pVal);
2787 if(FALSE == IS_VALID_BEACON(value))
2788 goto error;
2789 /** Write back the integer value. This is to avoid values like 01, 001, 0001
2790 * being written to the configuration
2791 */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002792 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002793 break;
2794
2795 case eCMD_DTIM_PERIOD:
2796 value = atoi(pVal);
2797 if(FALSE == IS_VALID_DTIM_PERIOD(value))
2798 goto error;
2799 /** Write back the integer value. This is to avoid values like 01, 001, 0001
2800 * being written to the configuration
2801 */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002802 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002803 break;
2804
2805 case eCMD_HW_MODE:
2806 status = FALSE;
2807 for(value=HW_MODE_B; value<HW_MODE_UNKNOWN; value++) {
2808 if(!strcmp(pVal, hw_mode[value])) {
2809 status = TRUE;
2810 break;
2811 }
2812 }
2813
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002814 if(status == FALSE)
2815 goto error;
2816
2817 ulen = MAX_FILE_PATH_LEN;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002818 /* pVal is anull terminated string */
2819 value = qsap_set_operating_mode(value, pVal, strlen(pVal)+1, filename, &ulen);
2820 *plen = qsap_scnprintf(presp, *plen, "%s", (value == eSUCCESS) ? SUCCESS : ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002821 return;
2822
2823 case eCMD_AUTH_ALGS:
2824 value = atoi(pVal);
2825 if((value != AHTH_ALG_OPEN) && (value != AUTH_ALG_SHARED) &&
2826 (value != AUTH_ALG_OPEN_SHARED))
2827 goto error;
2828 /** Write back the integer value. This is to avoid values like 01, 001, 0001
2829 * being written to the configuration
2830 */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002831 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002832 break;
2833
2834 case eCMD_DEFAULT_KEY:
2835 value = atoi(pVal);
2836 if(FALSE == IS_VALID_WEP_KEY_IDX(value))
2837 goto error;
2838 /** Write back the integer value. This is to avoid values like 01, 001, 0001
2839 * being written to the configuration
2840 */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002841 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
2842
Raj Kushwahaae27f822010-11-14 17:47:11 -08002843 qsap_write_cfg(pcfg, &cmd_list[cNum], pVal, presp, plen, ini);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002844
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002845 ulen = MAX_FILE_PATH_LEN;
2846 if(SEC_MODE_WEP != qsap_read_security_mode(pcfg, filename, &ulen)) {
Raj Kushwahaae27f822010-11-14 17:47:11 -08002847 if(eERR_UNKNOWN == qsap_change_cfg(pcfg, &cmd_list[cNum], 0)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302848 ALOGE("%s: eCMD_DEFAULT_KEY \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002849 goto error;
2850 }
2851 }
2852
2853 return;
2854
2855 case eCMD_WPA_PAIRWISE:
2856 case eCMD_RSN_PAIRWISE:
2857 if(FALSE == IS_VALID_PAIRWISE(pVal))
2858 goto error;
2859
2860 /** If the encryption type is TKIP, disable the 802.11 HT */
2861 value = 1;
2862 if(!strcmp(pVal, "TKIP")) {
2863 value = 0;
2864 }
2865
Raj Kushwahaae27f822010-11-14 17:47:11 -08002866 if(eERR_UNKNOWN == qsap_change_cfg(pconffile, &qsap_str[STR_HT_80211N], value)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302867 ALOGE("%s: unable to update 802.11 HT\n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002868 goto error;
2869 }
2870
2871 break;
2872
2873 case eCMD_WEP_KEY0:
2874 case eCMD_WEP_KEY1:
2875 case eCMD_WEP_KEY2:
2876 case eCMD_WEP_KEY3:
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002877 if(FALSE == is_valid_wep_key(pVal, filename, MAX_FILE_PATH_LEN))
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002878 goto error;
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002879
Raj Kushwahaae27f822010-11-14 17:47:11 -08002880 qsap_write_cfg(pcfg, &cmd_list[cNum], filename, presp, plen, ini);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002881
2882 /** if the security mode is not WEP, update the WEP features, and
2883 do NOT set the WEP security */
2884 ulen = MAX_FILE_PATH_LEN;
2885 if(SEC_MODE_WEP != qsap_read_security_mode(pcfg, filename, &ulen)) {
Raj Kushwahaae27f822010-11-14 17:47:11 -08002886 if(eERR_UNKNOWN == qsap_change_cfg(pcfg, &cmd_list[cNum], 0)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302887 ALOGE("%s: CMD_WEP_KEY0 \n", __func__);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002888 goto error;
2889 }
2890 }
2891
2892 return;
2893
2894 case eCMD_RESET_AP:
2895 value = atoi(pVal);
Deepthi Gowrid4c03152012-07-17 18:42:07 +05302896 ALOGE("Reset :%ld \n", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002897 if(SAP_RESET_BSS == value) {
2898 status = wifi_qsap_stop_softap();
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002899 if(status == eSUCCESS) {
2900 status = wifi_qsap_start_softap();
2901 if (eSUCCESS != status)
2902 wifi_qsap_unload_driver();
2903 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002904 }
2905 else if(SAP_RESET_DRIVER_BSS == value){
2906 status = wifi_qsap_reload_softap();
2907 }
2908 else if(SAP_STOP_BSS == value) {
2909 status = wifi_qsap_stop_bss();
2910 }
2911 else if(SAP_STOP_DRIVER_BSS == value) {
2912 status = wifi_qsap_stop_softap();
2913 if(status == eSUCCESS)
2914 status = wifi_qsap_unload_driver();
2915 }
Sameer Thalappilcaf87922012-01-30 16:56:29 -08002916#ifdef QCOM_WLAN_CONCURRENCY
2917 else if(SAP_INITAP == value) {
2918 status = wifi_qsap_start_softap_in_concurrency();
2919 }
2920 else if(SAP_EXITAP == value) {
2921 status = wifi_qsap_stop_softap_in_concurrency();
2922 }
2923#endif
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002924 else {
2925 status = !eSUCCESS;
2926 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002927 *plen = qsap_scnprintf(presp, *plen, "%s", (status == eSUCCESS) ? SUCCESS : ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002928 return;
2929
2930 case eCMD_DISASSOC_STA:
2931 qsap_disassociate_sta(pVal, presp, plen);
2932 return;
2933
2934 case eCMD_RESET_TO_DEFAULT:
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002935 if(eSUCCESS == (status = wifi_qsap_reset_to_default(pconffile, DEFAULT_CONFIG_FILE_PATH))) {
2936 if(eSUCCESS == (status = wifi_qsap_reset_to_default(fIni, DEFAULT_INI_FILE))) {
Raj Kushwaha13eb75f2011-03-12 10:21:45 -08002937 status = wifi_qsap_reload_softap();
Raj Kushwahaba862bd2010-09-17 00:34:16 -07002938 }
2939 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08002940 *plen = qsap_scnprintf(presp, *plen, "%s", (status == eSUCCESS) ? SUCCESS : ERR_UNKNOWN);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002941 return;
2942
2943 case eCMD_DATA_RATES:
2944 value = atoi(pVal);
2945 qsap_set_data_rate(value, presp, plen);
2946 return;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07002947 case eCMD_UUID:
2948 value = strlen(pVal);
2949 if(TRUE != IS_VALID_UUID_LEN(value))
2950 goto error;
2951 break;
2952 case eCMD_DEVICE_NAME:
2953 value = strlen(pVal);
2954 if(TRUE != IS_VALID_DEVICENAME_LEN(value))
2955 goto error;
2956 break;
2957 case eCMD_MANUFACTURER:
2958 value = strlen(pVal);
2959 if(TRUE != IS_VALID_MANUFACTURER_LEN(value))
2960 goto error;
2961 break;
2962
2963 case eCMD_MODEL_NAME:
2964 value = strlen(pVal);
2965 if(TRUE != IS_VALID_MODELNAME_LEN(value))
2966 goto error;
2967 break;
2968
2969 case eCMD_MODEL_NUMBER:
2970 value = strlen(pVal);
2971 if(TRUE != IS_VALID_MODELNUM_LEN(value))
2972 goto error;
2973 break;
2974
2975 case eCMD_SERIAL_NUMBER:
2976 value = strlen(pVal);
2977 if(TRUE != IS_VALID_SERIALNUM_LEN(value))
2978 goto error;
2979 break;
2980
2981 case eCMD_DEVICE_TYPE:
2982 value = strlen(pVal);
2983 if(TRUE != IS_VALID_DEV_TYPE_LEN(value))
2984 goto error;
2985 break;
2986
2987 case eCMD_OS_VERSION:
2988 value = strlen(pVal);
2989 if(TRUE != IS_VALID_OS_VERSION_LEN(value))
2990 goto error;
2991 break;
2992
2993 case eCMD_FRIENDLY_NAME:
2994 value = strlen(pVal);
2995 if(TRUE != IS_VALID_FRIENDLY_NAME_LEN(value))
2996 goto error;
2997 break;
2998
2999 case eCMD_MANUFACTURER_URL:
3000 case eCMD_MODEL_URL:
3001 value = strlen(pVal);
3002 if(TRUE != IS_VALID_URL_LEN(value))
3003 goto error;
3004 break;
3005
3006 case eCMD_MODEL_DESC:
3007 value = strlen(pVal);
3008 if(TRUE != IS_VALID_MODEL_DESC_LEN(value))
3009 goto error;
3010 break;
3011
3012 case eCMD_UPC:
3013 value = strlen(pVal);
3014 if(TRUE != IS_VALID_UPC_LEN(value))
3015 goto error;
3016 break;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003017 case eCMD_WMM_STATE:
3018 value = atoi(pVal);
3019 if(TRUE != IS_VALID_WMM_STATE(value))
3020 goto error;
3021
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003022 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003023 break;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003024 case eCMD_WPS_STATE:
3025 value = atoi(pVal);
3026 if(TRUE != IS_VALID_WPS_STATE(value))
3027 goto error;
3028 /** Write back the integer value. This is to avoid values like 01, 001, 0001
3029 * being written to the configuration
3030 */
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003031 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003032 qsap_update_wps_config(pVal, presp, plen);
3033 return;
3034
3035 case eCMD_WPS_CONFIG_METHOD:
3036 qsap_config_wps_method(pVal, presp, plen);
3037 return;
3038
3039 case eCMD_PROTECTION_FLAG:
3040 value = atoi(pVal);
3041 if(TRUE != IS_VALID_PROTECTION(value))
3042 goto error;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003043 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003044 cNum = STR_PROT_FLAG_IN_INI;
3045 ini = INI_CONF_FILE;
3046 break;
3047
3048 case eCMD_FRAG_THRESHOLD:
3049 value = atoi(pVal);
3050 if(TRUE != IS_VALID_FRAG_THRESHOLD(value))
3051 goto error;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003052 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003053 break;
3054
3055 case eCMD_REGULATORY_DOMAIN:
3056 value = atoi(pVal);
3057
3058 if(TRUE != IS_VALID_802DOT11D_STATE(value))
3059 goto error;
3060
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003061 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003062 break;
3063
3064 case eCMD_RTS_THRESHOLD:
3065 value = atoi(pVal);
3066 if(TRUE != IS_VALID_RTS_THRESHOLD(value))
3067 goto error;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003068 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003069 break;
3070
3071 case eCMD_GTK_TIMEOUT:
3072 value = atoi(pVal);
3073 if(TRUE != IS_VALID_GTK(value))
3074 goto error;
3075
3076 break;
3077
3078 case eCMD_TX_POWER:
3079 value = atoi(pVal);
3080 if(TRUE != IS_VALID_TX_POWER(value))
3081 goto error;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003082 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003083 cNum = STR_TX_POWER_IN_INI;
Deepthi Gowri6344a802012-01-12 17:11:18 +05303084 ini = INI_CONF_FILE;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003085 break;
3086
3087 case eCMD_INTRA_BSS_FORWARD:
3088 value = atoi(pVal);
3089 if(TRUE != IS_VALID_INTRA_BSS_STATUS(value))
3090 goto error;
3091
Deepthi Gowri6344a802012-01-12 17:11:18 +05303092 if(DISABLE == value) {
3093 status = qsap_change_cfg(pcfg,
3094 &cmd_list[eCMD_INTRA_BSS_FORWARD],DISABLE);
3095 }
3096 else {
3097 status = qsap_change_cfg(pcfg,
3098 &cmd_list[eCMD_INTRA_BSS_FORWARD],ENABLE);
3099 }
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003100 *plen = qsap_scnprintf(presp, *plen, "%s", (status == eSUCCESS) ?
Deepthi Gowri6344a802012-01-12 17:11:18 +05303101 SUCCESS : ERR_UNKNOWN);
3102 return;
Raj Kushwahaba862bd2010-09-17 00:34:16 -07003103
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003104 case eCMD_COUNTRY_CODE:
Santosh Sajjanc463f732011-12-22 18:24:56 +05303105 value = strlen(pVal);
3106 if(value > CTRY_MAX_LEN )
3107 goto error;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003108 break;
3109
Raj Kushwaha41027212010-10-13 00:11:12 -07003110 case eCMD_AP_AUTOSHUTOFF:
3111 value = atoi(pVal);
3112 if(TRUE != IS_VALID_APSHUTOFFTIME(value))
3113 goto error;
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003114 /* copy a larger value back to pVal. Please pay special care
3115 * in caller to make sure that the buffer has sufficient size. */
3116 qsap_scnprintf(pVal, MAX_INT_STR, "%ld", value*60);
Raj Kushwaha41027212010-10-13 00:11:12 -07003117 cNum = STR_AP_AUTOSHUTOFF;
3118 ini = INI_CONF_FILE;
3119 break;
3120
3121 case eCMD_AP_ENERGY_DETECT_TH:
3122 value = atoi(pVal);
3123 if(TRUE != IS_VALID_ENERGY_DETECT_TH(value))
3124 goto error;
3125
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003126 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
Raj Kushwaha41027212010-10-13 00:11:12 -07003127 cNum = STR_AP_ENERGY_DETECT_TH;
3128 ini = INI_CONF_FILE;
3129 break;
Pradeep Reddy POTTETI5c1a3ab2016-01-07 20:01:40 +05303130
3131 case eCMD_IEEE80211H:
3132 value = atoi(pVal);
3133 if(TRUE != IS_VALID_DFS_STATE(value))
3134 goto error;
3135
3136 qsap_scnprintf(pVal, strlen(pVal)+1, "%ld", value);
3137 break;
3138
Deepthi Gowri684d2f92012-05-23 23:28:16 +05303139 case eCMD_SET_CHANNEL_RANGE:
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303140 ALOGE("eCMD_SET_CHANNEL_RANGE pcmd :%s\n", pcmd);
Deepthi Gowri684d2f92012-05-23 23:28:16 +05303141 value = qsap_set_channel_range(pcmd);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003142 *plen = qsap_scnprintf(presp, *plen, "%s", (value == eSUCCESS) ? SUCCESS :
Deepthi Gowri684d2f92012-05-23 23:28:16 +05303143 ERR_UNKNOWN);
3144 return;
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303145 case eCMD_SSID2:
3146 /* Disable ssid while setting ssid2 */
3147 qsap_change_cfg(pcfg, &cmd_list[eCMD_SSID], DISABLE);
3148 break;
Raj Kushwaha41027212010-10-13 00:11:12 -07003149
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003150 default: ;
3151 /** Do not goto error, in default case */
3152 }
3153
3154 if(ini == INI_CONF_FILE) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303155 ALOGD("WRITE TO INI FILE :%s\n", qsap_str[cNum].name);
Raj Kushwahaae27f822010-11-14 17:47:11 -08003156 qsap_write_cfg(fIni, &qsap_str[cNum], pVal, presp, plen, ini);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003157 }
3158 else {
Raj Kushwahaae27f822010-11-14 17:47:11 -08003159 qsap_write_cfg(pcfg, &cmd_list[cNum], pVal, presp, plen, ini);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003160 }
3161
3162 return;
3163
3164error:
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003165 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALID_PARAM);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003166 return;
3167}
3168
3169/**
3170 * @brief
3171 * Initiate the command and return response
3172 * @param pcmd string containing the command request
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003173 * The format of the command is
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003174 * get param=value
3175 * or
3176 * set param=value
3177 * @param presp buffer to store the command response
3178 * @param plen length of the respone buffer
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003179 * @return
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003180 * void
3181*/
3182void qsap_hostd_exec_cmd(s8 *pcmd, s8 *presp, u32 *plen)
3183{
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303184 ALOGD("CMD INPUT [%s][%lu]\n", pcmd, *plen);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003185 /* Skip any blank spaces */
3186 SKIP_BLANK_SPACE(pcmd);
3187
Ajit Vaishyaa21d2652017-07-04 21:32:27 +05303188 if(!(strncmp(pcmd, Cmd_req[eCMD_SET], strlen(Cmd_req[eCMD_SET])))) {
3189 if(!(strncmp(pcmd+4, Conf_req[CONF_2g], strlen(Conf_req[CONF_2g])))) {
3190 pconffile = CONFIG_FILE_2G;
3191 } else if (!(strncmp(pcmd+4, Conf_req[CONF_5g], strlen(Conf_req[CONF_5g])))) {
3192 pconffile = CONFIG_FILE_5G;
Hu Wangd8555002018-12-06 18:13:00 +08003193 } else if (!(strncmp(pcmd+4, Conf_req[CONF_owe], strlen(Conf_req[CONF_owe])))) {
3194 pconffile = CONFIG_FILE_OWE;
Dedy Lanskya2dd08f2019-11-10 13:58:58 +02003195 } else if (!(strncmp(pcmd+4, Conf_req[CONF_60g], strlen(Conf_req[CONF_60g])))) {
3196 pconffile = CONFIG_FILE_60G;
Ajit Vaishyaa21d2652017-07-04 21:32:27 +05303197 } else {
3198 pconffile = CONFIG_FILE;
3199 }
3200 }
3201
Raj Kushwahaae27f822010-11-14 17:47:11 -08003202 check_for_configuration_files();
3203
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003204 if(!strncmp(pcmd, Cmd_req[eCMD_GET], strlen(Cmd_req[eCMD_GET])) && isblank(pcmd[strlen(Cmd_req[eCMD_GET])])) {
3205 qsap_handle_get_request(pcmd, presp, plen);
3206 }
3207
3208 else if(!(strncmp(pcmd, Cmd_req[eCMD_SET], strlen(Cmd_req[eCMD_SET]))) && isblank(pcmd[strlen(Cmd_req[eCMD_SET])]) ) {
3209 qsap_handle_set_request(pcmd, presp, plen);
3210 }
3211
3212 else {
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003213 *plen = qsap_scnprintf(presp, *plen, "%s", ERR_INVALIDREQ);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003214 }
3215
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303216 ALOGD("CMD OUTPUT [%s]\nlen :%lu\n\n", presp, *plen);
Mingcheng Zhu69b91cc2013-11-23 00:37:03 -08003217
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003218 return;
3219}
3220
3221/* netd and Froyo Native UI specific API */
Nalla Kartheekf4eef252016-04-29 18:09:35 +05303222#define DEFAULT_INTFERACE "wlan0"
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003223#define DEFAULT_SSID "SOFTAP_SSID"
3224#define DEFAULT_CHANNEL 4
3225#define DEFAULT_PASSPHRASE "12345678"
3226#define DEFAULT_AUTH_ALG 1
Raj Kushwahaae27f822010-11-14 17:47:11 -08003227#define RECV_BUF_LEN 255
3228#define CMD_BUF_LEN 255
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303229#define SET_BUF_LEN 15
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003230
3231/** Command input
Deepthi Gowrid0ea69c2012-12-26 14:08:38 +05303232 argv[3] = SSID,
Mahesh A Saptasagar41f17f12013-10-22 01:25:04 +05303233 argv[4] = BROADCAST/HIDDEN,
3234 argv[5] = CHANNEL
3235 argv[6] = SECURITY,
3236 argv[7] = KEY,
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003237*/
3238int qsapsetSoftap(int argc, char *argv[])
3239{
3240 char cmdbuf[CMD_BUF_LEN];
3241 char respbuf[RECV_BUF_LEN];
Ravi Joshi124fb552014-04-02 16:18:12 -07003242 u32 rlen = RECV_BUF_LEN;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003243 int i;
Mahesh A Saptasagard289ef32013-12-13 12:01:16 +05303244 int hidden = 0;
Raj Kushwahaae27f822010-11-14 17:47:11 -08003245 int sec = SEC_MODE_NONE;
Srinivas Dasaria7f00802017-08-27 21:54:10 +05303246 char setCmd[SET_BUF_LEN] = "set";
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303247 int offset = 0;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003248
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303249 ALOGD("%s, %s, %s, %d\n", __FUNCTION__, argv[0], argv[1], argc);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003250
3251 for ( i=0; i<argc;i++) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303252 ALOGD("ARG: %d - %s\n", i+1, argv[i]);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003253 }
3254
Dedy Lanskya2dd08f2019-11-10 13:58:58 +02003255 // check if 2nd arg is dual2g/dual5g/owe/60g
Hu Wangd8555002018-12-06 18:13:00 +08003256 if (argc > 2
3257 && (strncmp(argv[2], Conf_req[CONF_2g], 4) == 0
Dedy Lanskya2dd08f2019-11-10 13:58:58 +02003258 || strncmp(argv[2], Conf_req[CONF_owe], 3) == 0
3259 || strncmp(argv[2], Conf_req[CONF_60g], 3) == 0)) {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303260 snprintf(setCmd, SET_BUF_LEN, "set %s", argv[2]);
3261 offset = 1;
3262 argc--;
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303263 }
3264
Nalla Kartheekf4eef252016-04-29 18:09:35 +05303265 /* set interface */
3266 if (argc > 2) {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303267 snprintf(cmdbuf, CMD_BUF_LEN, "%s interface=%s", setCmd, argv[2 + offset]);
Nalla Kartheekf4eef252016-04-29 18:09:35 +05303268 }
3269 else {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303270 snprintf(cmdbuf, CMD_BUF_LEN, "%s interface=%s", setCmd, DEFAULT_INTFERACE);
Nalla Kartheekf4eef252016-04-29 18:09:35 +05303271 }
3272 (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
3273
3274
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003275 /** set SSID */
Deepthi Gowrid0ea69c2012-12-26 14:08:38 +05303276 if(argc > 3) {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303277 // In case of dual2g/5g, Set ssid2 with hex values to accomodate sapce and special characters.
3278 if (offset)
3279 qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s ssid2=%s", setCmd, argv[3 + offset]);
3280 else
3281 qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s ssid=%s",setCmd, argv[3]);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003282 }
3283 else {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303284 qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s ssid=%s_%d", setCmd, DEFAULT_SSID, rand());
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003285 }
3286 (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
3287
3288 if(strncmp("success", respbuf, rlen) != 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303289 ALOGE("Failed to set ssid\n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003290 return eERR_UNKNOWN;
3291 }
3292
Mahesh A Saptasagar41f17f12013-10-22 01:25:04 +05303293 rlen = RECV_BUF_LEN;
3294 if (argc > 4) {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303295 if (strcmp(argv[4 + offset], "hidden") == 0) {
Mahesh A Saptasagard289ef32013-12-13 12:01:16 +05303296 hidden = 1;
3297 }
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303298 snprintf(cmdbuf, CMD_BUF_LEN, "%s ignore_broadcast_ssid=%d", setCmd, hidden);
Mahesh A Saptasagar41f17f12013-10-22 01:25:04 +05303299 (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
3300 if(strncmp("success", respbuf, rlen) != 0) {
3301 ALOGE("Failed to set ignore_broadcast_ssid \n");
3302 return -1;
3303 }
3304 }
3305 /** channel */
3306 rlen = RECV_BUF_LEN;
3307 if(argc > 5) {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303308 snprintf(cmdbuf, CMD_BUF_LEN, "%s channel=%d", setCmd, atoi(argv[5 + offset]));
Mahesh A Saptasagar41f17f12013-10-22 01:25:04 +05303309 (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
3310
3311 if(strncmp("success", respbuf, rlen) != 0) {
3312 ALOGE("Failed to set channel \n");
3313 return -1;
3314 }
3315 }
Mahesh A Saptasagar4a7a4592013-12-16 13:46:58 +05303316
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003317 /** Security */
3318 rlen = RECV_BUF_LEN;
Mahesh A Saptasagar41f17f12013-10-22 01:25:04 +05303319 if(argc > 6) {
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003320
3321 /**TODO : need to identify the SEC strings for "wep", "wpa", "wpa2" */
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303322 if(!strcmp(argv[6 + offset], "open"))
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003323 sec = SEC_MODE_NONE;
3324
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303325 else if(!strcmp(argv[6 + offset], "wep"))
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003326 sec = SEC_MODE_WEP;
3327
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303328 else if(!strcmp(argv[6 + offset], "wpa-psk"))
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003329 sec = SEC_MODE_WPA_PSK;
3330
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303331 else if(!strcmp(argv[6 + offset], "wpa2-psk"))
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003332 sec = SEC_MODE_WPA2_PSK;
3333
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303334 qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s security_mode=%d",setCmd, sec);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003335 }
3336 else {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303337 qsap_scnprintf(cmdbuf, sizeof(cmdbuf) , "%s security_mode=%d", setCmd, DEFAULT_AUTH_ALG);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003338 }
3339
3340 (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
3341
3342 if(strncmp("success", respbuf, rlen) != 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303343 ALOGE("Failed to set security mode\n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003344 return -1;
3345 }
3346
3347 /** Key -- passphrase */
3348 rlen = RECV_BUF_LEN;
Raj Kushwahaae27f822010-11-14 17:47:11 -08003349 if ( (sec == SEC_MODE_WPA_PSK) || (sec == SEC_MODE_WPA2_PSK) ) {
Mahesh A Saptasagar41f17f12013-10-22 01:25:04 +05303350 if(argc > 7) {
Raj Kushwahaae27f822010-11-14 17:47:11 -08003351 /* If the input passphrase is more than 63 characters, consider first 63 characters only*/
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303352 if ( strlen(argv[7 + offset]) > 63 ) argv[7 + offset][63] = '\0';
3353 qsap_scnprintf(cmdbuf, CMD_BUF_LEN, "%s wpa_passphrase=%s",setCmd, argv[7 + offset]);
Raj Kushwahaae27f822010-11-14 17:47:11 -08003354 }
3355 else {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303356 qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s wpa_passphrase=%s", setCmd, DEFAULT_PASSPHRASE);
Raj Kushwahaae27f822010-11-14 17:47:11 -08003357 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003358 }
3359
3360 (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
Raj Kushwahaae27f822010-11-14 17:47:11 -08003361 if(strncmp("success", respbuf, rlen) != 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303362 ALOGE("Failed to set passphrase \n");
Raj Kushwahaae27f822010-11-14 17:47:11 -08003363 return -1;
3364 }
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003365
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003366 rlen = RECV_BUF_LEN;
Changzhi Dengfddc6be2015-05-21 15:47:07 +08003367 if(argc > 8) {
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303368 qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s max_num_sta=%d",setCmd, atoi(argv[8 + offset]));
Changzhi Dengfddc6be2015-05-21 15:47:07 +08003369 }
3370 (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
3371
3372 if(strncmp("success", respbuf, rlen) != 0) {
3373 ALOGE("Failed to set maximun client connections number \n");
3374 return -1;
3375 }
3376 rlen = RECV_BUF_LEN;
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003377
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303378 qsap_scnprintf(cmdbuf, sizeof(cmdbuf), "%s commit", setCmd);
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003379
3380 (void) qsap_hostd_exec_cmd(cmdbuf, respbuf, &rlen);
3381
3382 if(strncmp("success", respbuf, rlen) != 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303383 ALOGE("Failed to COMMIT \n");
Raj Kushwahaaaaa5182010-08-25 14:12:16 -07003384 return -1;
3385 }
3386
3387 return 0;
3388}
Raj Kushwahaae27f822010-11-14 17:47:11 -08003389
Ravi Joshi8b0be842014-03-07 13:51:42 -08003390
3391static int check_for_config_file_size(FILE *fp)
3392{
3393 int length = 0;
3394
3395 if( NULL != fp )
3396 {
3397 fseek(fp, 0L, SEEK_END);
3398 length = ftell(fp);
3399 }
3400
3401 return length;
3402}
3403
Raj Kushwahaae27f822010-11-14 17:47:11 -08003404void check_for_configuration_files(void)
3405{
3406 FILE * fp;
Pradeep Reddy POTTETIa1c6f1d2015-09-18 18:49:05 +05303407 char *pfile;
Raj Kushwahaae27f822010-11-14 17:47:11 -08003408
3409 /* Check if configuration files are present, if not create the default files */
Raj Kushwahaae27f822010-11-14 17:47:11 -08003410
Deepthi Gowri80a36e22012-10-16 18:33:51 +05303411 /* If configuration file does not exist copy the default file */
Ajit Vaishyaa21d2652017-07-04 21:32:27 +05303412 if ( NULL == (fp = fopen(pconffile, "r")) ) {
3413 wifi_qsap_reset_to_default(pconffile, DEFAULT_CONFIG_FILE_PATH);
Raj Kushwahaae27f822010-11-14 17:47:11 -08003414 }
3415 else {
Ravi Joshi8b0be842014-03-07 13:51:42 -08003416
3417 /* The configuration file could be of 0 byte size, replace with default */
3418 if (check_for_config_file_size(fp) <= 0)
Ajit Vaishyaa21d2652017-07-04 21:32:27 +05303419 wifi_qsap_reset_to_default(pconffile, DEFAULT_CONFIG_FILE_PATH);
Ravi Joshi8b0be842014-03-07 13:51:42 -08003420
Raj Kushwahaae27f822010-11-14 17:47:11 -08003421 fclose(fp);
3422 }
3423
Deepthi Gowri80a36e22012-10-16 18:33:51 +05303424 /* If Accept MAC list file does not exist, copy the default file */
Raj Kushwahaae27f822010-11-14 17:47:11 -08003425 if ( NULL == (fp = fopen(ACCEPT_LIST_FILE, "r")) ) {
Deepthi Gowri80a36e22012-10-16 18:33:51 +05303426 wifi_qsap_reset_to_default(ACCEPT_LIST_FILE, DEFAULT_ACCEPT_LIST_FILE_PATH);
Raj Kushwahaae27f822010-11-14 17:47:11 -08003427 }
3428 else {
Ravi Joshi8b0be842014-03-07 13:51:42 -08003429
3430 /* The configuration file could be of 0 byte size, replace with default */
3431 if (check_for_config_file_size(fp) <= 0)
3432 wifi_qsap_reset_to_default(ACCEPT_LIST_FILE, DEFAULT_ACCEPT_LIST_FILE_PATH);
3433
Raj Kushwahaae27f822010-11-14 17:47:11 -08003434 fclose(fp);
3435 }
3436
Pradeep Reddy POTTETIa1c6f1d2015-09-18 18:49:05 +05303437 /* Provide read and write permissions to the owner */
3438 pfile = ACCEPT_LIST_FILE;
3439 if (chmod(pfile, 0660) < 0) {
3440 ALOGE("Error changing permissions of %s to 0660: %s",
3441 pfile, strerror(errno));
3442 }
Deepthi Gowri80a36e22012-10-16 18:33:51 +05303443 /* If deny MAC list file does not exist, copy the default file */
Raj Kushwahaae27f822010-11-14 17:47:11 -08003444 if ( NULL == (fp = fopen(DENY_LIST_FILE, "r")) ) {
Deepthi Gowri80a36e22012-10-16 18:33:51 +05303445 wifi_qsap_reset_to_default(DENY_LIST_FILE, DEFAULT_DENY_LIST_FILE_PATH);
Raj Kushwahaae27f822010-11-14 17:47:11 -08003446 }
3447 else {
Ravi Joshi8b0be842014-03-07 13:51:42 -08003448
3449 /* The configuration file could be of 0 byte size, replace with default */
3450 if (check_for_config_file_size(fp) <= 0)
3451 wifi_qsap_reset_to_default(DENY_LIST_FILE, DEFAULT_DENY_LIST_FILE_PATH);
3452
Raj Kushwahaae27f822010-11-14 17:47:11 -08003453 fclose(fp);
3454 }
3455
Pradeep Reddy POTTETIa1c6f1d2015-09-18 18:49:05 +05303456 /* Provide read and write permissions to the owner */
3457 pfile = DENY_LIST_FILE;
3458 if (chmod(pfile, 0660) < 0) {
3459 ALOGE("Error changing permissions of %s to 0660: %s",
3460 pfile, strerror(errno));
3461 }
Raj Kushwahaae27f822010-11-14 17:47:11 -08003462 return;
3463}
Yunsen Wang458db7c2011-11-15 21:23:32 -08003464
3465void qsap_set_ini_filename(void)
3466{
3467 if (property_get("wlan.driver.config", ini_file, NULL)) {
3468 fIni = ini_file;
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303469 ALOGE("INI FILE PROP PRESENT %s\n", fIni);
Yunsen Wang458db7c2011-11-15 21:23:32 -08003470 } else
Deepthi Gowrid4c03152012-07-17 18:42:07 +05303471 ALOGE("INI FILE PROP NOT PRESENT: Use default path %s\n", fIni);
Yunsen Wang458db7c2011-11-15 21:23:32 -08003472 return;
3473}
Nalla Kartheekf4eef252016-04-29 18:09:35 +05303474
Ajit Vaishya5d72c3a2017-07-15 20:22:10 +05303475// IOCTL command to create and delete bridge interface //
3476#ifndef SIOCBRADDBR
3477#define SIOCBRADDBR 0x89a0
3478#endif
3479#ifndef SIOCBRDELBR
3480#define SIOCBRDELBR 0x89a1
3481#endif
3482
3483static int linux_set_iface_flags(int sock, const char *ifname, int dev_up)
3484{
3485 struct ifreq ifr;
3486 int ret;
3487
3488 if (sock < 0)
3489 return -1;
3490
3491 memset(&ifr, 0, sizeof(ifr));
3492 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
3493
3494 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
3495 ret = errno ? -errno : -999;
3496 ALOGE("Could not read interface %s flags: %s",
3497 ifname, strerror(errno));
3498 return ret;
3499 }
3500
3501 if (dev_up) {
3502 if (ifr.ifr_flags & IFF_UP)
3503 return 0;
3504 ifr.ifr_flags |= IFF_UP;
3505 } else {
3506 if (!(ifr.ifr_flags & IFF_UP))
3507 return 0;
3508 ifr.ifr_flags &= ~IFF_UP;
3509 }
3510
3511 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
3512 ret = errno ? -errno : -999;
3513 ALOGE("Could not set interface %s flags (%s): %s",
3514 ifname, dev_up ? "UP" : "DOWN", strerror(errno));
3515 return ret;
3516 }
3517 return 0;
3518}
3519
3520int qsap_control_bridge(int argc, char ** argv)
3521{
3522 int br_socket;
3523
3524 if (argc < 4) {
3525 ALOGE("Command not supported");
3526 return -1;
3527 }
3528
3529 br_socket = socket(PF_INET, SOCK_DGRAM, 0);
3530 if (br_socket < 0) {
3531 ALOGE("socket(PF_INET,SOCK_DGRAM): %s",strerror(errno));
3532 return -1;
3533 }
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303534 if (!strncmp(argv[2],"create", 6)) {
Ajit Vaishya5d72c3a2017-07-15 20:22:10 +05303535 if (ioctl(br_socket, SIOCBRADDBR, argv[3]) < 0) {
3536 ALOGE("Could not add bridge %s: %s", argv[3], strerror(errno));
3537 return -1;
3538 }
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303539 } else if (!strncmp(argv[2],"remove", 6)) {
Ajit Vaishya5d72c3a2017-07-15 20:22:10 +05303540 if (ioctl(br_socket, SIOCBRDELBR, argv[3]) < 0) {
3541 ALOGE("Could not add remove %s: %s", argv[3], strerror(errno));
3542 return -1;
3543 }
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303544 } else if (!strncmp(argv[2],"up", 2)) {
Ajit Vaishya5d72c3a2017-07-15 20:22:10 +05303545 return linux_set_iface_flags(br_socket, argv[3], 1);
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303546 } else if (!strncmp(argv[2],"down", 4)) {
Ajit Vaishya5d72c3a2017-07-15 20:22:10 +05303547 return linux_set_iface_flags(br_socket, argv[3], 0);
3548 } else {
3549 ALOGE("Command %s not handled.", argv[2]);
3550 return -1;
3551 }
3552
3553 return 0;
3554}
3555
Purushottam Kushwahaa7c3aa82017-07-21 22:03:58 +05303556
Purushottam Kushwaha0e5ec062017-07-21 22:11:45 +05303557int linux_get_ifhwaddr(const char *ifname, char *addr)
3558{
3559 struct ifreq ifr;
3560 int sock = socket(AF_INET, SOCK_DGRAM, 0);
3561
3562#ifndef MAC2STR
3563#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
3564#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
3565#endif
3566 memset(&ifr, 0, sizeof(ifr));
3567 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
3568 if (ioctl(sock, SIOCGIFHWADDR, &ifr)) {
3569 ALOGE("Could not get interface %s hwaddr: %s", ifname, strerror(errno));
3570 return -1;
3571 }
3572
3573 if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
3574 ALOGE("%s: Invalid HW-addr family 0x%04x", ifname, ifr.ifr_hwaddr.sa_family);
3575 return -1;
3576 }
3577 memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
3578 ALOGE("%s: " MACSTR, ifname, MAC2STR(addr));
3579
3580 return 0;
3581}
3582
3583
Nalla Kartheekf4eef252016-04-29 18:09:35 +05303584int qsap_add_or_remove_interface(const char *newIface , int createIface)
3585{
3586 const char *wlanIface = "wlan0";
3587 int retVal = 0;
3588 struct nl_msg *msg = NULL;
3589 struct nl_cb *cb = NULL;
3590 struct nl_cb *s_cb = NULL;
3591 struct nl_sock *nl_sock = NULL;
3592 int nl80211_id;
3593 enum nl80211_iftype type = NL80211_IFTYPE_AP;
3594
3595 /* Allocate a netlink socket */
3596 s_cb = nl_cb_alloc(NL_CB_DEFAULT);
3597 if (!s_cb) {
3598 ALOGE( "Failed to allocate Netlink Socket");
3599 retVal = -ENOMEM;
3600 goto nla_put_failure;
3601 }
3602
3603 nl_sock = nl_socket_alloc_cb(s_cb);
3604 if (!nl_sock) {
3605 ALOGE( "Netlink socket Allocation failure");
3606 retVal = -ENOMEM;
3607 goto nla_put_failure;
3608 }
3609
3610 /* connect to generic netlink socket */
3611 if (genl_connect(nl_sock)) {
3612 ALOGE( "Netlink socket Connection failure");
3613 retVal = -ENOLINK;
3614 goto nla_put_failure;
3615 }
3616
3617 nl80211_id = genl_ctrl_resolve(nl_sock, "nl80211");
3618 if (nl80211_id < 0) {
3619 ALOGE( "nl80211 generic netlink not found");
3620 retVal = -ENOENT;
3621 goto nla_put_failure;
3622 }
3623
3624 msg = nlmsg_alloc();
3625 if(!msg) {
3626 ALOGE( "Failed to allocate netlink message");
3627 retVal = -ENOMEM;
3628 goto nla_put_failure;
3629 }
3630
3631 cb = nl_cb_alloc(NL_CB_DEFAULT);
3632 if (!cb) {
3633 ALOGE( "Failed to allocate netlink callback");
3634 retVal = -ENOMEM;
3635 goto nla_put_failure;
3636 }
3637
3638 if (createIface == 1) {
3639 /* Issue NL80211_CMD_NEW_INTERFACE */
3640 genlmsg_put( msg, 0, 0, nl80211_id, 0, 0, NL80211_CMD_NEW_INTERFACE, 0);
3641 nla_put_u32( msg, NL80211_ATTR_IFINDEX, if_nametoindex( wlanIface ));
3642 NLA_PUT_STRING( msg, NL80211_ATTR_IFNAME, newIface);
3643 nla_put_u32( msg, NL80211_ATTR_IFTYPE, type);
3644 } else {
3645 genlmsg_put( msg, 0, 0, nl80211_id, 0, 0, NL80211_CMD_DEL_INTERFACE, 0);
3646 nla_put_u32( msg, NL80211_ATTR_IFINDEX, if_nametoindex( newIface ));
3647 }
3648
3649 retVal = nl_send_auto_complete(nl_sock, msg );
3650 if (retVal < 0 ) {
3651 goto nla_put_failure;
3652 }
3653 else {
3654 ALOGD("Interface %s is %s - Ok", (createIface == 1 ? "created":"removed") ,newIface);
3655 }
3656nla_put_failure:
3657 if (nl_sock)
3658 nl_socket_free(nl_sock);
3659 if (s_cb)
3660 nl_cb_put(s_cb);
3661 if (msg)
3662 nlmsg_free(msg);
3663 if (cb)
3664 nl_cb_put(cb);
3665 return retVal;
3666}