blob: b06baf1ef351461e7bdde12dc27a8724169af56c [file] [log] [blame]
Srinivas Dasaridc488942018-01-24 19:35:19 +05301/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
Ahmad Kholaif159de4f2015-03-23 16:02:05 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "sync.h"
30#define LOG_TAG "WifiHAL"
31#include <utils/Log.h>
32#include <time.h>
Ajay Dudani65b8c552015-04-11 22:52:06 -070033#include <errno.h>
Amarnath Hullur Subramanyamb131c772015-08-06 14:22:50 -070034#include <stdlib.h>
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -080035#include <unistd.h>
Khanjan Desai80f78492020-03-03 00:04:51 +053036#include <string>
37#include <net/if.h>
38#include <vector>
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070039#include "wificonfigcommand.h"
40
41/* Implementation of the API functions exposed in wifi_config.h */
42wifi_error wifi_extended_dtim_config_set(wifi_request_id id,
43 wifi_interface_handle iface,
44 int extended_dtim)
45{
Srinivas Dasari30b13c72017-08-08 15:44:23 +053046 wifi_error ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070047 WiFiConfigCommand *wifiConfigCommand;
48 struct nlattr *nlData;
49 interface_info *ifaceInfo = getIfaceInfo(iface);
50 wifi_handle wifiHandle = getWifiHandle(iface);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070051
Subhani Shaikeb97b6e2016-03-29 11:33:25 +053052 ALOGV("%s: extended_dtim:%d", __FUNCTION__, extended_dtim);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070053
54 wifiConfigCommand = new WiFiConfigCommand(
55 wifiHandle,
56 id,
57 OUI_QCA,
58 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
59
60 if (wifiConfigCommand == NULL) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +053061 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070062 return WIFI_ERROR_UNKNOWN;
63 }
64
65 /* Create the NL message. */
66 ret = wifiConfigCommand->create();
Srinivas Dasari30b13c72017-08-08 15:44:23 +053067 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070068 ALOGE("wifi_extended_dtim_config_set: failed to create NL msg. "
69 "Error:%d", ret);
70 goto cleanup;
71 }
72
73 /* Set the interface Id of the message. */
74 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
Srinivas Dasari30b13c72017-08-08 15:44:23 +053075 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070076 ALOGE("wifi_extended_dtim_config_set: failed to set iface id. "
77 "Error:%d", ret);
78 goto cleanup;
79 }
80
81 /* Add the vendor specific attributes for the NL command. */
82 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
83 if (!nlData) {
84 ALOGE("wifi_extended_dtim_config_set: failed attr_start for "
85 "VENDOR_DATA. Error:%d", ret);
86 goto cleanup;
87 }
88
Srinivas Dasari30b13c72017-08-08 15:44:23 +053089 ret = wifiConfigCommand->put_u32(
Srinivas Dasaric0854c72018-06-14 16:55:55 +053090 QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_DTIM, extended_dtim);
Srinivas Dasari30b13c72017-08-08 15:44:23 +053091 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -070092 ALOGE("wifi_extended_dtim_config_set(): failed to put vendor data. "
93 "Error:%d", ret);
94 goto cleanup;
95 }
96 wifiConfigCommand->attr_end(nlData);
97
98 /* Send the NL msg. */
99 wifiConfigCommand->waitForRsp(false);
100 ret = wifiConfigCommand->requestEvent();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530101 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700102 ALOGE("wifi_extended_dtim_config_set(): requestEvent Error:%d", ret);
103 goto cleanup;
104 }
105
106cleanup:
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700107 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530108 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700109}
110
Peng Xu2eef57d2018-03-14 14:11:37 -0700111int check_feature(enum qca_wlan_vendor_features feature, features_info *info)
112{
113 size_t idx = feature / 8;
114
115 return (idx < info->flags_len) &&
116 (info->flags[idx] & BIT(feature % 8));
117}
118
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700119/* Set the country code to driver. */
120wifi_error wifi_set_country_code(wifi_interface_handle iface,
121 const char* country_code)
122{
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530123 int requestId;
124 wifi_error ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700125 WiFiConfigCommand *wifiConfigCommand;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700126 wifi_handle wifiHandle = getWifiHandle(iface);
Peng Xu2eef57d2018-03-14 14:11:37 -0700127 hal_info *info = getHalInfo(wifiHandle);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700128
Subhani Shaikeb97b6e2016-03-29 11:33:25 +0530129 ALOGV("%s: %s", __FUNCTION__, country_code);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700130
131 /* No request id from caller, so generate one and pass it on to the driver.
132 * Generate it randomly.
133 */
Amarnath Hullur Subramanyamb131c772015-08-06 14:22:50 -0700134 requestId = get_requestid();
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700135
136 wifiConfigCommand = new WiFiConfigCommand(
137 wifiHandle,
138 requestId,
139 OUI_QCA,
140 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
141 if (wifiConfigCommand == NULL) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530142 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700143 return WIFI_ERROR_UNKNOWN;
144 }
145
146 /* Create the NL message with NL80211_CMD_REQ_SET_REG NL cmd. */
147 ret = wifiConfigCommand->create_generic(NL80211_CMD_REQ_SET_REG);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530148 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700149 ALOGE("wifi_set_country_code: failed to create NL msg. Error:%d", ret);
150 goto cleanup;
151 }
152
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530153 ret = wifiConfigCommand->put_string(NL80211_ATTR_REG_ALPHA2, country_code);
154 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700155 ALOGE("wifi_set_country_code: put country code failed. Error:%d", ret);
156 goto cleanup;
157 }
158
Peng Xu2eef57d2018-03-14 14:11:37 -0700159 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY,
160 &info->driver_supported_features)) {
161 ret = wifiConfigCommand->put_u32(NL80211_ATTR_USER_REG_HINT_TYPE,
162 NL80211_USER_REG_HINT_CELL_BASE);
163 if (ret != WIFI_SUCCESS) {
164 ALOGE("wifi_set_country_code: put reg hint type failed. Error:%d",
165 ret);
166 goto cleanup;
167 }
168 }
169
170
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700171 /* Send the NL msg. */
172 wifiConfigCommand->waitForRsp(false);
173 ret = wifiConfigCommand->requestEvent();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530174 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700175 ALOGE("wifi_set_country_code(): requestEvent Error:%d", ret);
176 goto cleanup;
177 }
Srinivas Dasari02d14ee2015-08-19 16:52:08 +0530178 usleep(WAIT_TIME_FOR_SET_REG_DOMAIN);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700179
180cleanup:
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700181 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530182 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700183}
184
Jian Tang95979d72017-11-16 16:52:30 +0800185/*
186 * Set the powersave to driver.
187 */
188wifi_error wifi_set_qpower(wifi_interface_handle iface,
189 u8 powersave)
190{
191 int requestId, ret = 0;
192 WiFiConfigCommand *wifiConfigCommand;
193 struct nlattr *nlData;
194 interface_info *ifaceInfo = getIfaceInfo(iface);
195 wifi_handle wifiHandle = getWifiHandle(iface);
196 //hal_info *info = getHalInfo(wifiHandle);
197
198 ALOGD("%s: %d", __FUNCTION__, powersave);
199
200 requestId = get_requestid();
201
202 wifiConfigCommand = new WiFiConfigCommand(
203 wifiHandle,
204 requestId,
205 OUI_QCA,
206 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
207
208 if (wifiConfigCommand == NULL) {
209 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
210 return WIFI_ERROR_UNKNOWN;
211 }
212
213 /* Create the NL message. */
214 ret = wifiConfigCommand->create();
215 if (ret < 0) {
216 ALOGE("wifi_set_qpower: failed to create NL msg. "
217 "Error:%d", ret);
218 goto cleanup;
219 }
220
221 /* Set the interface Id of the message. */
222 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
223 if (ret < 0) {
224 ALOGE("wifi_set_qpower: failed to set iface id. "
225 "Error:%d", ret);
226 goto cleanup;
227 }
228
229 /* Add the vendor specific attributes for the NL command. */
230 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
231 if (!nlData) {
232 ALOGE("wifi_set_qpower: failed attr_start for "
233 "VENDOR_DATA. Error:%d", ret);
234 goto cleanup;
235 }
236
237 if (wifiConfigCommand->put_u8(
Srinivas Dasaric0854c72018-06-14 16:55:55 +0530238 QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER, powersave)) {
Jian Tang95979d72017-11-16 16:52:30 +0800239 ALOGE("wifi_set_qpower(): failed to put vendor data. "
240 "Error:%d", ret);
241 goto cleanup;
242 }
243 wifiConfigCommand->attr_end(nlData);
244
245 /* Send the NL msg. */
246 wifiConfigCommand->waitForRsp(false);
247 ret = wifiConfigCommand->requestEvent();
248 if (ret != 0) {
249 ALOGE("wifi_set_qpower(): requestEvent Error:%d", ret);
250 goto cleanup;
251 }
252
253cleanup:
254 delete wifiConfigCommand;
255 return (wifi_error)ret;
256
257}
258
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700259wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor(
260 wifi_request_id id,
261 wifi_interface_handle iface,
262 u16 factor)
263{
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530264 wifi_error ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700265 WiFiConfigCommand *wifiConfigCommand;
266 struct nlattr *nlData;
267 interface_info *ifaceInfo = getIfaceInfo(iface);
268 wifi_handle wifiHandle = getWifiHandle(iface);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700269
Subhani Shaikeb97b6e2016-03-29 11:33:25 +0530270 ALOGV("%s factor:%u", __FUNCTION__, factor);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700271 wifiConfigCommand = new WiFiConfigCommand(
272 wifiHandle,
273 id,
274 OUI_QCA,
275 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
276 if (wifiConfigCommand == NULL) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530277 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700278 return WIFI_ERROR_UNKNOWN;
279 }
280
281 /* Create the NL message. */
282 ret = wifiConfigCommand->create();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530283 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700284 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to "
285 "create NL msg. Error:%d", ret);
286 goto cleanup;
287 }
288
289 /* Set the interface Id of the message. */
290 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530291 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700292 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to "
293 "set iface id. Error:%d", ret);
294 goto cleanup;
295 }
296
297 /* Add the vendor specific attributes for the NL command. */
298 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
299 if (!nlData) {
300 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed "
301 "attr_start for VENDOR_DATA. Error:%d", ret);
302 goto cleanup;
303 }
304
305 if (wifiConfigCommand->put_u32(
Srinivas Dasaric0854c72018-06-14 16:55:55 +0530306 QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR, factor)) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700307 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): failed to "
308 "put vendor data. Error:%d", ret);
309 goto cleanup;
310 }
311 wifiConfigCommand->attr_end(nlData);
312
313 /* Send the NL msg. */
314 wifiConfigCommand->waitForRsp(false);
315 ret = wifiConfigCommand->requestEvent();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530316 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700317 ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): "
318 "requestEvent Error:%d", ret);
319 goto cleanup;
320 }
321
322cleanup:
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700323 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530324 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700325}
326
327wifi_error wifi_set_guard_time(wifi_request_id id,
328 wifi_interface_handle iface,
329 u32 guard_time)
330{
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530331 wifi_error ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700332 WiFiConfigCommand *wifiConfigCommand;
333 struct nlattr *nlData;
334 interface_info *ifaceInfo = getIfaceInfo(iface);
335 wifi_handle wifiHandle = getWifiHandle(iface);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700336
Subhani Shaikeb97b6e2016-03-29 11:33:25 +0530337 ALOGV("%s : guard_time:%u", __FUNCTION__, guard_time);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700338
339 wifiConfigCommand = new WiFiConfigCommand(
340 wifiHandle,
341 id,
342 OUI_QCA,
343 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
344 if (wifiConfigCommand == NULL) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530345 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700346 return WIFI_ERROR_UNKNOWN;
347 }
348
349 /* Create the NL message. */
350 ret = wifiConfigCommand->create();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530351 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700352 ALOGE("wifi_set_guard_time: failed to create NL msg. Error:%d", ret);
353 goto cleanup;
354 }
355
356 /* Set the interface Id of the message. */
357 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530358 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700359 ALOGE("wifi_set_guard_time: failed to set iface id. Error:%d", ret);
360 goto cleanup;
361 }
362
363 /* Add the vendor specific attributes for the NL command. */
364 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
365 if (!nlData) {
366 ALOGE("wifi_set_guard_time: failed attr_start for VENDOR_DATA. "
367 "Error:%d", ret);
368 goto cleanup;
369 }
370
371 if (wifiConfigCommand->put_u32(
Srinivas Dasaric0854c72018-06-14 16:55:55 +0530372 QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME, guard_time)) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700373 ALOGE("wifi_set_guard_time: failed to add vendor data.");
374 goto cleanup;
375 }
376 wifiConfigCommand->attr_end(nlData);
377
378 /* Send the NL msg. */
379 wifiConfigCommand->waitForRsp(false);
380 ret = wifiConfigCommand->requestEvent();
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530381 if (ret != WIFI_SUCCESS) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700382 ALOGE("wifi_set_guard_time(): requestEvent Error:%d", ret);
383 goto cleanup;
384 }
385
386cleanup:
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700387 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530388 return ret;
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800389}
390
391wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle,
392 wifi_power_scenario scenario)
393{
394 wifi_error ret;
395 WiFiConfigCommand *wifiConfigCommand;
396 struct nlattr *nlData;
397 interface_info *ifaceInfo = getIfaceInfo(handle);
398 wifi_handle wifiHandle = getWifiHandle(handle);
399 u32 bdf_file = 0;
400
401 ALOGV("%s : power scenario:%d", __FUNCTION__, scenario);
402
403 wifiConfigCommand = new WiFiConfigCommand(
404 wifiHandle,
405 1,
406 OUI_QCA,
407 QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS);
408 if (wifiConfigCommand == NULL) {
409 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
410 return WIFI_ERROR_UNKNOWN;
411 }
412
413 /* Create the NL message. */
414 ret = wifiConfigCommand->create();
415 if (ret != WIFI_SUCCESS) {
416 ALOGE("wifi_select_tx_power_scenario: failed to create NL msg. Error:%d", ret);
417 goto cleanup;
418 }
419
420 /* Set the interface Id of the message. */
421 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
422 if (ret != WIFI_SUCCESS) {
423 ALOGE("wifi_select_tx_power_scenario: failed to set iface id. Error:%d", ret);
424 goto cleanup;
425 }
426
427 /* Add the vendor specific attributes for the NL command. */
428 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
429 if (!nlData) {
430 ALOGE("wifi_select_tx_power_scenario: failed attr_start for VENDOR_DATA. "
431 "Error:%d", ret);
432 goto cleanup;
433 }
434
Srinivas Girigowda8e444fd2018-04-12 07:53:40 -0700435 switch (scenario) {
436 case WIFI_POWER_SCENARIO_VOICE_CALL:
437 case WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF:
438 bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0;
439 break;
440
441 case WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON:
442 bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1;
443 break;
444
445 case WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF:
446 bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2;
447 break;
448
449 case WIFI_POWER_SCENARIO_ON_BODY_CELL_ON:
450 bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3;
451 break;
452
453 default:
454 ALOGE("wifi_select_tx_power_scenario: invalid scenario %d", scenario);
455 ret = WIFI_ERROR_INVALID_ARGS;
456 goto cleanup;
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800457 }
Srinivas Girigowda8e444fd2018-04-12 07:53:40 -0700458
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800459 if (wifiConfigCommand->put_u32(
460 QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE,
461 bdf_file)) {
462 ALOGE("failed to put SAR_ENABLE");
463 goto cleanup;
464 }
465 wifiConfigCommand->attr_end(nlData);
466
467 ret = wifiConfigCommand->requestEvent();
468 if (ret != WIFI_SUCCESS) {
469 ALOGE("wifi_select_tx_power_scenario(): requestEvent Error:%d", ret);
470 goto cleanup;
471 }
472
473cleanup:
474 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530475 return ret;
Srinivas Girigowda2bba36f2018-01-29 15:43:59 -0800476}
477
478wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle)
479{
480 wifi_error ret;
481 WiFiConfigCommand *wifiConfigCommand;
482 struct nlattr *nlData;
483 interface_info *ifaceInfo = getIfaceInfo(handle);
484 wifi_handle wifiHandle = getWifiHandle(handle);
485
486 wifiConfigCommand = new WiFiConfigCommand(
487 wifiHandle,
488 1,
489 OUI_QCA,
490 QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS);
491 if (wifiConfigCommand == NULL) {
492 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
493 return WIFI_ERROR_UNKNOWN;
494 }
495
496 /* Create the NL message. */
497 ret = wifiConfigCommand->create();
498 if (ret != WIFI_SUCCESS) {
499 ALOGE("wifi_reset_tx_power_scenario: failed to create NL msg. Error:%d", ret);
500 goto cleanup;
501 }
502
503 /* Set the interface Id of the message. */
504 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
505 if (ret != WIFI_SUCCESS) {
506 ALOGE("wifi_reset_tx_power_scenario: failed to set iface id. Error:%d", ret);
507 goto cleanup;
508 }
509
510 /* Add the vendor specific attributes for the NL command. */
511 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
512 if (!nlData) {
513 ALOGE("wifi_reset_tx_power_scenario: failed attr_start for VENDOR_DATA. "
514 "Error:%d", ret);
515 goto cleanup;
516 }
517
518 if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE,
519 QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE)) {
520 ALOGE("failed to put SAR_ENABLE or NUM_SPECS");
521 goto cleanup;
522 }
523 wifiConfigCommand->attr_end(nlData);
524
525 ret = wifiConfigCommand->requestEvent();
526 if (ret != WIFI_SUCCESS) {
527 ALOGE("wifi_reset_tx_power_scenario(): requestEvent Error:%d", ret);
528 goto cleanup;
529 }
530
531cleanup:
532 delete wifiConfigCommand;
Srinivas Dasaridc488942018-01-24 19:35:19 +0530533 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700534}
535
Vamsi Krishna4b90cd52020-02-03 10:11:34 +0530536wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle,
537 wifi_thermal_mode mode,
538 u32 completion_window)
539{
540 wifi_error ret;
541 WiFiConfigCommand *wifiConfigCommand;
542 struct nlattr *nlData;
543 u32 qca_vendor_thermal_level;
544 hal_info *info = getHalInfo(handle);
545
546 if (!info || info->num_interfaces < 1) {
547 ALOGE("%s: Error wifi_handle NULL or base wlan interface not present",
548 __FUNCTION__);
549 return WIFI_ERROR_UNKNOWN;
550 }
551
552 wifiConfigCommand = new WiFiConfigCommand(
553 handle,
554 1,
555 OUI_QCA,
556 QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD);
557 if (wifiConfigCommand == NULL) {
558 ALOGE("%s: Error, Failed to create wifiConfigCommand", __FUNCTION__);
559 return WIFI_ERROR_UNKNOWN;
560 }
561
562 /* Create the NL message. */
563 ret = wifiConfigCommand->create();
564 if (ret != WIFI_SUCCESS) {
565 ALOGE("Failed to create thermal vendor command, Error:%d", ret);
566 goto cleanup;
567 }
568
569 /* Set the interface Id of the message. */
570 if (wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
571 info->interfaces[0]->id)) {
572 ALOGE("%s: Failed to put iface id", __FUNCTION__);
573 goto cleanup;
574 }
575
576 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
577 if (!nlData) {
578 ALOGE("%s: Failed in attr_start for VENDOR_DATA, Error:%d",
579 __FUNCTION__, ret);
580 goto cleanup;
581 }
582
583 if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE,
584 QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL)) {
585 ALOGE("Failed to put THERMAL_LEVEL command type");
586 goto cleanup;
587 }
588
589 switch(mode) {
590 case WIFI_MITIGATION_NONE:
591 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE;
592 break;
593 case WIFI_MITIGATION_LIGHT:
594 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT;
595 break;
596 case WIFI_MITIGATION_MODERATE:
597 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE;
598 break;
599 case WIFI_MITIGATION_SEVERE:
600 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE;
601 break;
602 case WIFI_MITIGATION_CRITICAL:
603 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL;
604 break;
605 case WIFI_MITIGATION_EMERGENCY:
606 qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY;
607 break;
608 default:
609 ALOGE("Unknown thermal mitigation level %d", mode);
610 ret = WIFI_ERROR_UNKNOWN;
611 goto cleanup;
612 }
613
614 if (wifiConfigCommand->put_u32(
615 QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL,
616 qca_vendor_thermal_level)) {
617 ALOGE("Failed to put thermal level");
618 goto cleanup;
619 }
620
621 if (wifiConfigCommand->put_u32(
622 QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW,
623 completion_window)) {
624 ALOGE("Failed to put thermal completion window");
625 goto cleanup;
626 }
627 wifiConfigCommand->attr_end(nlData);
628
629 wifiConfigCommand->waitForRsp(false);
630 ret = wifiConfigCommand->requestEvent();
631 if (ret != WIFI_SUCCESS) {
632 ALOGE("Failed to set thermal level with Error: %d", ret);
633 goto cleanup;
634 }
635
636cleanup:
637 delete wifiConfigCommand;
638 return ret;
639}
640
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700641WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle,
642 int id, u32 vendor_id,
643 u32 subcmd)
644 : WifiVendorCommand(handle, id, vendor_id, subcmd)
645{
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700646 /* Initialize the member data variables here */
647 mWaitforRsp = false;
648 mRequestId = id;
649}
650
651WiFiConfigCommand::~WiFiConfigCommand()
652{
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700653 unregisterVendorHandler(mVendor_id, mSubcmd);
654}
655
656/* This function implements creation of Vendor command */
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530657wifi_error WiFiConfigCommand::create()
658{
659 wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
660 if (ret != WIFI_SUCCESS)
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700661 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700662
663 /* Insert the oui in the msg */
664 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530665 if (ret != WIFI_SUCCESS)
666 return ret;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700667 /* Insert the subcmd in the msg */
668 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530669
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700670 return ret;
671}
672
673/* This function implements creation of generic NL command */
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530674wifi_error WiFiConfigCommand::create_generic(u8 cmdId)
675{
676 wifi_error ret = mMsg.create(cmdId, 0, 0);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700677 return ret;
678}
679
680void WiFiConfigCommand::waitForRsp(bool wait)
681{
682 mWaitforRsp = wait;
683}
684
685/* Callback handlers registered for nl message send */
686static int error_handler_wifi_config(struct sockaddr_nl *nla,
687 struct nlmsgerr *err,
688 void *arg)
689{
690 struct sockaddr_nl *tmp;
691 int *ret = (int *)arg;
692 tmp = nla;
693 *ret = err->error;
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530694 ALOGE("%s: Error code:%d (%s)", __FUNCTION__, *ret, strerror(-(*ret)));
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700695 return NL_STOP;
696}
697
698/* Callback handlers registered for nl message send */
699static int ack_handler_wifi_config(struct nl_msg *msg, void *arg)
700{
701 int *ret = (int *)arg;
702 struct nl_msg * a;
703
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700704 a = msg;
705 *ret = 0;
706 return NL_STOP;
707}
708
709/* Callback handlers registered for nl message send */
710static int finish_handler_wifi_config(struct nl_msg *msg, void *arg)
711{
712 int *ret = (int *)arg;
713 struct nl_msg * a;
714
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700715 a = msg;
716 *ret = 0;
717 return NL_SKIP;
718}
719
720/*
721 * Override base class requestEvent and implement little differently here.
722 * This will send the request message.
723 * We don't wait for any response back in case of wificonfig,
724 * thus no wait for condition.
725 */
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530726wifi_error WiFiConfigCommand::requestEvent()
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700727{
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530728 int status;
729 wifi_error res = WIFI_SUCCESS;
Hu Wangc1a19012019-04-15 15:35:12 +0800730 struct nl_cb *cb = NULL;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700731
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700732 cb = nl_cb_alloc(NL_CB_DEFAULT);
733 if (!cb) {
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530734 ALOGE("%s: Callback allocation failed",__FUNCTION__);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530735 res = WIFI_ERROR_OUT_OF_MEMORY;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700736 goto out;
737 }
738
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530739 status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
740 if (status < 0) {
741 res = mapKernelErrortoWifiHalError(status);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700742 goto out;
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530743 }
744 status = 1;
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700745
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530746 nl_cb_err(cb, NL_CB_CUSTOM, error_handler_wifi_config, &status);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700747 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_wifi_config,
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530748 &status);
749 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_wifi_config, &status);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700750
751 /* Err is populated as part of finish_handler. */
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530752 while (status > 0) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700753 nl_recvmsgs(mInfo->cmd_sock, cb);
754 }
755
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530756 if (status < 0) {
757 res = mapKernelErrortoWifiHalError(status);
758 goto out;
759 }
760
761 if (mWaitforRsp == true) {
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700762 struct timespec abstime;
763 abstime.tv_sec = 4;
764 abstime.tv_nsec = 0;
765 res = mCondition.wait(abstime);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530766 if (res == WIFI_ERROR_TIMED_OUT)
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530767 ALOGE("%s: Time out happened.", __FUNCTION__);
Srinivas Dasari30b13c72017-08-08 15:44:23 +0530768
Subhani Shaikeb97b6e2016-03-29 11:33:25 +0530769 ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d",
Dasari Srinivas9b3d8d42015-09-10 11:16:45 +0530770 __FUNCTION__, res, mWaitforRsp);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700771 }
772out:
Hu Wangc1a19012019-04-15 15:35:12 +0800773 nl_cb_put(cb);
Ahmad Kholaif159de4f2015-03-23 16:02:05 -0700774 /* Cleanup the mMsg */
775 mMsg.destroy();
776 return res;
777}
778
Khanjan Desai80f78492020-03-03 00:04:51 +0530779
780
781static std::vector<std::string> added_ifaces;
782
783static bool is_dynamic_interface(const char * ifname)
784{
785 for (const auto& iface : added_ifaces) {
786 if (iface == std::string(ifname))
787 return true;
788 }
789 return false;
790}
791
792void wifi_cleanup_dynamic_ifaces(wifi_handle handle)
793{
794 int len = added_ifaces.size();
795 while (len--) {
796 wifi_virtual_interface_delete(handle, added_ifaces.front().c_str());
797 }
798 added_ifaces.clear(); // could be redundent. But to be on safe side.
799}
800
801wifi_error wifi_virtual_interface_create(wifi_handle handle,
802 const char* ifname,
803 wifi_interface_type iface_type)
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530804{
805 wifi_error ret;
806 WiFiConfigCommand *wifiConfigCommand;
Khanjan Desai80f78492020-03-03 00:04:51 +0530807 u32 wlan0_id = if_nametoindex("wlan0");
808 if (!handle || !wlan0_id) {
809 ALOGE("%s: Error wifi_handle NULL or wlan0 not present", __FUNCTION__);
810 return WIFI_ERROR_UNKNOWN;
811 }
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530812
Khanjan Desai80f78492020-03-03 00:04:51 +0530813 ALOGD("%s: ifname=%s create", __FUNCTION__, ifname);
814 // Do not create interface if already exist.
815 if (if_nametoindex(ifname))
816 return WIFI_SUCCESS;
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530817
Khanjan Desai80f78492020-03-03 00:04:51 +0530818 wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0);
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530819 if (wifiConfigCommand == NULL) {
820 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
821 return WIFI_ERROR_UNKNOWN;
822 }
823
Khanjan Desai80f78492020-03-03 00:04:51 +0530824 nl80211_iftype type;
825 switch(iface_type) {
826 case WIFI_INTERFACE_TYPE_STA: /* IfaceType:STA */
827 type = NL80211_IFTYPE_STATION;
828 break;
829 case WIFI_INTERFACE_TYPE_AP: /* IfaceType:AP */
830 type = NL80211_IFTYPE_AP;
831 break;
832 case WIFI_INTERFACE_TYPE_P2P: /* IfaceType:P2P */
833 type = NL80211_IFTYPE_P2P_DEVICE;
834 break;
Swarn Singhc2c9bc82019-12-05 18:08:27 +0530835 case WIFI_INTERFACE_TYPE_NAN: /* IfaceType:NAN */
836 type = NL80211_IFTYPE_NAN;
837 break;
Khanjan Desai80f78492020-03-03 00:04:51 +0530838 default:
839 ALOGE("%s: Wrong interface type %u", __FUNCTION__, iface_type);
840 ret = WIFI_ERROR_UNKNOWN;
841 goto done;
842 break;
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530843 }
Khanjan Desai80f78492020-03-03 00:04:51 +0530844 wifiConfigCommand->create_generic(NL80211_CMD_NEW_INTERFACE);
845 wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, wlan0_id);
846 wifiConfigCommand->put_string(NL80211_ATTR_IFNAME, ifname);
847 wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE, type);
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530848 /* Send the NL msg. */
849 wifiConfigCommand->waitForRsp(false);
850 ret = wifiConfigCommand->requestEvent();
Khanjan Desai80f78492020-03-03 00:04:51 +0530851 if (ret != WIFI_SUCCESS) {
852 ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret);
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530853 }
Khanjan Desai80f78492020-03-03 00:04:51 +0530854 // Update dynamic interface list
855 added_ifaces.push_back(std::string(ifname));
Purushottam Kushwahae1cf8f92018-06-08 17:47:53 +0530856
857done:
858 delete wifiConfigCommand;
859 return ret;
860}
Hu Wang38714b62018-11-08 19:57:21 +0800861
Khanjan Desai80f78492020-03-03 00:04:51 +0530862wifi_error wifi_virtual_interface_delete(wifi_handle handle,
863 const char* ifname)
864{
865 wifi_error ret;
866 WiFiConfigCommand *wifiConfigCommand;
867 u32 wlan0_id = if_nametoindex("wlan0");
868
869 if (!handle || !wlan0_id) {
870 ALOGE("%s: Error wifi_handle NULL or wlan0 not present", __FUNCTION__);
871 return WIFI_ERROR_UNKNOWN;
872 }
873
874 ALOGD("%s: ifname=%s delete", __FUNCTION__, ifname);
875 if (if_nametoindex(ifname) && !is_dynamic_interface(ifname)) {
876 // Do not remove interface if it was not added dynamically.
877 return WIFI_SUCCESS;
878 }
879 wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0);
880 if (wifiConfigCommand == NULL) {
881 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
882 return WIFI_ERROR_UNKNOWN;
883 }
884 wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
885 wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
886 /* Send the NL msg. */
887 wifiConfigCommand->waitForRsp(false);
888 ret = wifiConfigCommand->requestEvent();
889 if (ret != WIFI_SUCCESS) {
890 ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret);
891 }
892 // Update dynamic interface list
893 added_ifaces.erase(std::remove(added_ifaces.begin(), added_ifaces.end(), std::string(ifname)),
894 added_ifaces.end());
895
896 delete wifiConfigCommand;
897 return ret;
898}
899
900#ifdef WCNSS_QTI_AOSP
Hu Wang38714b62018-11-08 19:57:21 +0800901/**
902 * Set latency level
903 */
904wifi_error wifi_set_latency_mode(wifi_interface_handle iface,
905 wifi_latency_mode mode)
906{
907 int requestId, ret = 0;
Hu Wangc1936352019-04-25 15:26:03 +0800908 u16 level;
Hu Wang38714b62018-11-08 19:57:21 +0800909 WiFiConfigCommand *wifiConfigCommand;
910 struct nlattr *nlData;
911 interface_info *ifaceInfo = getIfaceInfo(iface);
912 wifi_handle wifiHandle = getWifiHandle(iface);
913
914 ALOGD("%s: %d", __FUNCTION__, mode);
915
Hu Wangc1936352019-04-25 15:26:03 +0800916 switch (mode) {
917 case WIFI_LATENCY_MODE_NORMAL:
918 level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
919 break;
920 case WIFI_LATENCY_MODE_LOW:
921 level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW;
922 break;
923 default:
924 ALOGI("%s: Unsupported latency mode=%d, resetting to NORMAL!", __FUNCTION__, mode);
925 level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
926 break;
927 }
928
Hu Wang38714b62018-11-08 19:57:21 +0800929 requestId = get_requestid();
930
931 wifiConfigCommand = new WiFiConfigCommand(
932 wifiHandle,
933 requestId,
934 OUI_QCA,
935 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION);
936
937 if (wifiConfigCommand == NULL) {
938 ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
939 return WIFI_ERROR_UNKNOWN;
940 }
941
942 /* Create the NL message. */
943 ret = wifiConfigCommand->create();
944 if (ret < 0) {
945 ALOGE("%s: failed to create NL msg. Error:%d",
946 __FUNCTION__, ret);
947 goto cleanup;
948 }
949
950 /* Set the interface Id of the message. */
951 ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
952 if (ret < 0) {
953 ALOGE("%s: failed to set iface id. Error:%d",
954 __FUNCTION__, ret);
955 goto cleanup;
956 }
957
958 /* Add the vendor specific attributes for the NL command. */
959 nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
960 if (!nlData) {
961 ALOGE("%s: failed attr_start for VENDOR_DATA. Error:%d",
962 __FUNCTION__, ret);
963 goto cleanup;
964 }
965
966 if (wifiConfigCommand->put_u16(
Hu Wangc1936352019-04-25 15:26:03 +0800967 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL, level)) {
Hu Wang38714b62018-11-08 19:57:21 +0800968 ALOGE("%s: failed to put vendor data. Error:%d",
969 __FUNCTION__, ret);
970 goto cleanup;
971 }
972 wifiConfigCommand->attr_end(nlData);
973
974 /* Send the NL msg. */
975 wifiConfigCommand->waitForRsp(false);
976 ret = wifiConfigCommand->requestEvent();
977 if (ret != 0) {
978 ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
979 goto cleanup;
980 }
981
982cleanup:
983 delete wifiConfigCommand;
984 return (wifi_error)ret;
985}
Hans Chang04ada2a2018-08-28 14:53:31 -0700986#endif