1 /* Copyright (c) 2014, 2018 The Linux Foundation. All rights reserved.
2 *
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 copyright
9 * notice, this list of conditions and the following disclaimer in
10 * the documentation and/or other materials provided with the
11 * 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>
33 #include <errno.h>
34
35 #include "ifaceeventhandler.h"
36 #include "common.h"
37
38 /* Used to handle NL command events from driver/firmware. */
39 IfaceEventHandlerCommand *mwifiEventHandler = NULL;
40
41 /* Set the interface event monitor handler*/
wifi_set_iface_event_handler(wifi_request_id id,wifi_interface_handle iface,wifi_event_handler eh)42 wifi_error wifi_set_iface_event_handler(wifi_request_id id,
43 wifi_interface_handle iface,
44 wifi_event_handler eh)
45 {
46 wifi_handle wifiHandle = getWifiHandle(iface);
47
48 /* Check if a similar request to set iface event handler was made earlier.
49 * Right now we don't differentiate between the case where (i) the new
50 * Request Id is different from the current one vs (ii) both new and
51 * Request Ids are the same.
52 */
53 if (mwifiEventHandler)
54 {
55 if (id == mwifiEventHandler->get_request_id()) {
56 ALOGE("%s: Iface Event Handler Set for request Id %d is still"
57 "running. Exit", __func__, id);
58 return WIFI_ERROR_TOO_MANY_REQUESTS;
59 } else {
60 ALOGE("%s: Iface Event Handler Set for a different Request "
61 "Id:%d is requested. Not supported. Exit", __func__, id);
62 return WIFI_ERROR_NOT_SUPPORTED;
63 }
64 }
65
66 mwifiEventHandler = new IfaceEventHandlerCommand(
67 wifiHandle,
68 id,
69 NL80211_CMD_REG_CHANGE);
70 if (mwifiEventHandler == NULL) {
71 ALOGE("%s: Error mwifiEventHandler NULL", __func__);
72 return WIFI_ERROR_UNKNOWN;
73 }
74 mwifiEventHandler->setCallbackHandler(eh);
75
76 return WIFI_SUCCESS;
77 }
78
79 /* Reset monitoring for the NL event*/
wifi_reset_iface_event_handler(wifi_request_id id,wifi_interface_handle iface)80 wifi_error wifi_reset_iface_event_handler(wifi_request_id id,
81 wifi_interface_handle iface)
82 {
83 if (mwifiEventHandler)
84 {
85 if (id == mwifiEventHandler->get_request_id()) {
86 ALOGV("Delete Object mwifiEventHandler for id = %d", id);
87 delete mwifiEventHandler;
88 mwifiEventHandler = NULL;
89 } else {
90 ALOGE("%s: Iface Event Handler Set for a different Request "
91 "Id:%d is requested. Not supported. Exit", __func__, id);
92 return WIFI_ERROR_NOT_SUPPORTED;
93 }
94 } else {
95 ALOGV("Object mwifiEventHandler for id = %d already Deleted", id);
96 }
97
98 return WIFI_SUCCESS;
99 }
100
101 /* This function will be the main handler for the registered incoming
102 * (from driver) Commads. Calls the appropriate callback handler after
103 * parsing the vendor data.
104 */
handleEvent(WifiEvent & event)105 int IfaceEventHandlerCommand::handleEvent(WifiEvent &event)
106 {
107 wifiEventHandler::handleEvent(event);
108
109 switch(mSubcmd)
110 {
111 case NL80211_CMD_REG_CHANGE:
112 {
113 char code[2];
114 memset(&code[0], 0, 2);
115 if(tb[NL80211_ATTR_REG_ALPHA2])
116 {
117 memcpy(&code[0], (char *) nla_data(tb[NL80211_ATTR_REG_ALPHA2]), 2);
118 } else {
119 ALOGE("%s: NL80211_ATTR_REG_ALPHA2 not found", __func__);
120 }
121 ALOGV("Country : %c%c", code[0], code[1]);
122 if(mHandler.on_country_code_changed)
123 {
124 mHandler.on_country_code_changed(code);
125 }
126 }
127 break;
128 default:
129 ALOGV("NL Event : %d Not supported", mSubcmd);
130 }
131
132 return NL_SKIP;
133 }
134
IfaceEventHandlerCommand(wifi_handle handle,int id,u32 subcmd)135 IfaceEventHandlerCommand::IfaceEventHandlerCommand(wifi_handle handle, int id, u32 subcmd)
136 : wifiEventHandler(handle, id, subcmd)
137 {
138 ALOGV("wifiEventHandler %p constructed", this);
139 registerHandler(mSubcmd);
140 memset(&mHandler, 0, sizeof(wifi_event_handler));
141 mEventData = NULL;
142 mDataLen = 0;
143 }
144
~IfaceEventHandlerCommand()145 IfaceEventHandlerCommand::~IfaceEventHandlerCommand()
146 {
147 ALOGV("IfaceEventHandlerCommand %p destructor", this);
148 unregisterHandler(mSubcmd);
149 }
150
setCallbackHandler(wifi_event_handler nHandler)151 void IfaceEventHandlerCommand::setCallbackHandler(wifi_event_handler nHandler)
152 {
153 mHandler = nHandler;
154 }
155
get_request_id()156 int wifiEventHandler::get_request_id()
157 {
158 return mRequestId;
159 }
160
get_request_id()161 int IfaceEventHandlerCommand::get_request_id()
162 {
163 return wifiEventHandler::get_request_id();
164 }
165
wifiEventHandler(wifi_handle handle,int id,u32 subcmd)166 wifiEventHandler::wifiEventHandler(wifi_handle handle, int id, u32 subcmd)
167 : WifiCommand(handle, id)
168 {
169 mRequestId = id;
170 mSubcmd = subcmd;
171 registerHandler(mSubcmd);
172 ALOGV("wifiEventHandler %p constructed", this);
173 }
174
~wifiEventHandler()175 wifiEventHandler::~wifiEventHandler()
176 {
177 ALOGV("wifiEventHandler %p destructor", this);
178 unregisterHandler(mSubcmd);
179 }
180
handleEvent(WifiEvent & event)181 int wifiEventHandler::handleEvent(WifiEvent &event)
182 {
183 struct genlmsghdr *gnlh = event.header();
184 mSubcmd = gnlh->cmd;
185 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
186 genlmsg_attrlen(gnlh, 0), NULL);
187 ALOGV("Got NL Event : %d from the Driver.", gnlh->cmd);
188
189 return NL_SKIP;
190 }
191
WifihalGeneric(wifi_handle handle,int id,u32 vendor_id,u32 subcmd)192 WifihalGeneric::WifihalGeneric(wifi_handle handle, int id, u32 vendor_id,
193 u32 subcmd)
194 : WifiVendorCommand(handle, id, vendor_id, subcmd)
195 {
196 hal_info *info = getHalInfo(handle);
197
198 /* Initialize the member data variables here */
199 mSet = 0;
200 mSetSizeMax = 0;
201 mSetSizePtr = NULL;
202 mConcurrencySet = 0;
203 filterVersion = 0;
204 filterLength = 0;
205 firmware_bus_max_size = 0;
206 mCapa = &(info->capa);
207 mfilter_packet_read_buffer = NULL;
208 mfilter_packet_length = 0;
209 res_size = 0;
210 channel_buff = NULL;
211 memset(&mDriverFeatures, 0, sizeof(mDriverFeatures));
212 memset(&mRadarResultParams, 0, sizeof(RadarHistoryResultsParams));
213 }
214
~WifihalGeneric()215 WifihalGeneric::~WifihalGeneric()
216 {
217 mCapa = NULL;
218 if (mDriverFeatures.flags != NULL) {
219 free(mDriverFeatures.flags);
220 mDriverFeatures.flags = NULL;
221 }
222 }
223
requestResponse()224 wifi_error WifihalGeneric::requestResponse()
225 {
226 return WifiCommand::requestResponse(mMsg);
227 }
228
get_wifi_iftype_masks(u32 in_mask)229 static u32 get_wifi_iftype_masks(u32 in_mask)
230 {
231 u32 op_mask = 0;
232
233 if (in_mask & BIT(NL80211_IFTYPE_STATION)) {
234 op_mask |= BIT(WIFI_INTERFACE_STA);
235 op_mask |= BIT(WIFI_INTERFACE_TDLS);
236 }
237 if (in_mask & BIT(NL80211_IFTYPE_AP))
238 op_mask |= BIT(WIFI_INTERFACE_SOFTAP);
239 if (in_mask & BIT(NL80211_IFTYPE_P2P_CLIENT))
240 op_mask |= BIT(WIFI_INTERFACE_P2P_CLIENT);
241 if (in_mask & BIT(NL80211_IFTYPE_P2P_GO))
242 op_mask |= BIT(WIFI_INTERFACE_P2P_GO);
243 if (in_mask & BIT(NL80211_IFTYPE_NAN))
244 op_mask |= BIT(WIFI_INTERFACE_NAN);
245
246 return op_mask;
247 }
248
get_channel_width(u32 nl_width)249 static wifi_channel_width get_channel_width(u32 nl_width)
250 {
251 switch(nl_width) {
252 case NL80211_CHAN_WIDTH_20:
253 return WIFI_CHAN_WIDTH_20;
254 case NL80211_CHAN_WIDTH_40:
255 return WIFI_CHAN_WIDTH_40;
256 case NL80211_CHAN_WIDTH_80:
257 return WIFI_CHAN_WIDTH_80;
258 case NL80211_CHAN_WIDTH_160:
259 return WIFI_CHAN_WIDTH_160;
260 case NL80211_CHAN_WIDTH_80P80:
261 return WIFI_CHAN_WIDTH_80P80;
262 case NL80211_CHAN_WIDTH_5:
263 return WIFI_CHAN_WIDTH_5;
264 case NL80211_CHAN_WIDTH_10:
265 return WIFI_CHAN_WIDTH_10;
266 default:
267 return WIFI_CHAN_WIDTH_INVALID;
268 }
269 }
270
handle_response_usable_channels(struct nlattr * VendorData,u32 mDataLen)271 int WifihalGeneric::handle_response_usable_channels(struct nlattr *VendorData,
272 u32 mDataLen)
273 {
274 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX + 1];
275 struct nlattr *curr_attr;
276 wifi_usable_channel *chan_info = NULL;
277 int rem;
278 u32 currSize = 0;
279
280 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX,
281 (struct nlattr *)mVendorData, mDataLen, NULL)) {
282 ALOGE("Failed to parse NL channels list");
283 return WIFI_ERROR_INVALID_ARGS;
284 }
285
286 if (!tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO]) {
287 ALOGE("%s: USABLE_CHANNELS_CHAN_INFO not found", __FUNCTION__);
288 return WIFI_ERROR_INVALID_ARGS;
289 }
290
291 for_each_nested_attribute(curr_attr,
292 tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO], rem) {
293 struct nlattr *ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX + 1];
294
295 if (currSize >= mSetSizeMax) {
296 ALOGE("Got max channels %d completed", mSetSizeMax);
297 break;
298 }
299
300 if (nla_parse_nested(ch_info, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX,
301 curr_attr, NULL)) {
302 ALOGE("Failed to get usable channel info");
303 return NL_SKIP;
304 }
305
306 chan_info = &channel_buff[currSize];
307 if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]) {
308 ALOGE("%s: CHAN_INFO_PRIMARY_FREQ not found",
309 __FUNCTION__);
310 return NL_SKIP;
311 }
312
313 chan_info->freq = nla_get_u32(ch_info[
314 QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]);
315 if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH]) {
316 ALOGE("%s: CHAN_INFO_BANDWIDTH not found",
317 __FUNCTION__);
318 return NL_SKIP;
319 }
320
321 chan_info->width = get_channel_width(nla_get_u32(
322 ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH]));
323 if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK]) {
324 ALOGE("%s: CHAN_INFO_IFACE_MODE_MASK not found",
325 __FUNCTION__);
326 return NL_SKIP;
327 }
328
329 chan_info->iface_mode_mask = get_wifi_iftype_masks(nla_get_u32(
330 ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK]));
331 ALOGV("Primary freq %d BW %d iface mask %d", chan_info->freq,
332 chan_info->width, chan_info->iface_mode_mask);
333 currSize++;
334 }
335
336 res_size = currSize;
337 ALOGV("%s: Result size %d", __FUNCTION__, res_size);
338
339 return NL_SKIP;
340 }
341
handleResponse(WifiEvent & reply)342 int WifihalGeneric::handleResponse(WifiEvent &reply)
343 {
344 ALOGV("Got a Wi-Fi HAL module message from Driver");
345 int i = 0;
346 WifiVendorCommand::handleResponse(reply);
347
348 // Parse the vendordata and get the attribute
349 switch(mSubcmd)
350 {
351 case QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES:
352 {
353 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX + 1];
354 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX,
355 (struct nlattr *)mVendorData,
356 mDataLen, NULL);
357
358 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET])
359 {
360 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_FEATURE_SET not found", __func__);
361 return -EINVAL;
362 }
363 mSet = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET]);
364 ALOGV("Supported feature set : %" PRIx64, mSet);
365
366 break;
367 }
368 case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
369 {
370 struct nlattr *attr;
371 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
372 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
373 (struct nlattr *)mVendorData, mDataLen, NULL);
374 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
375 if (attr) {
376 int len = nla_len(attr);
377 mDriverFeatures.flags = (u8 *)malloc(len);
378 if (mDriverFeatures.flags != NULL) {
379 memcpy(mDriverFeatures.flags, nla_data(attr), len);
380 mDriverFeatures.flags_len = len;
381 }
382 }
383 break;
384 }
385 case QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX:
386 {
387 struct nlattr *tb_vendor[
388 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
389 nla_parse(tb_vendor,
390 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
391 (struct nlattr *)mVendorData,mDataLen, NULL);
392
393 if (tb_vendor[
394 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE]) {
395 u32 val;
396 val = nla_get_u32(
397 tb_vendor[
398 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE]);
399
400 ALOGV("%s: Num of concurrency combinations: %d",
401 __func__, val);
402 val = val > (unsigned int)mSetSizeMax ?
403 (unsigned int)mSetSizeMax : val;
404 *mSetSizePtr = val;
405
406 /* Extract the list of channels. */
407 if (*mSetSizePtr > 0 &&
408 tb_vendor[
409 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET]) {
410 nla_memcpy(mConcurrencySet,
411 tb_vendor[
412 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET],
413 sizeof(feature_set) * (*mSetSizePtr));
414 }
415
416 ALOGV("%s: Get concurrency matrix response received.",
417 __func__);
418 ALOGV("%s: Num of concurrency combinations : %d",
419 __func__, *mSetSizePtr);
420 ALOGV("%s: List of valid concurrency combinations is: ",
421 __func__);
422 for(i = 0; i < *mSetSizePtr; i++)
423 {
424 ALOGV("%" PRIx64, *(mConcurrencySet + i));
425 }
426 }
427 }
428 break;
429 case QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER:
430 {
431 int subCmd;
432 struct nlattr *tb_vendor[
433 QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX + 1];
434 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX,
435 (struct nlattr *)mVendorData,
436 mDataLen, NULL);
437
438 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD])
439 {
440 subCmd = nla_get_u32(
441 tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD]);
442 } else {
443 /*
444 * The older drivers may not send PACKET_FILTER_SUB_CMD as
445 * they support QCA_WLAN_GET_PACKET_FILTER only.
446 */
447 subCmd = QCA_WLAN_GET_PACKET_FILTER;
448 }
449 if (subCmd == QCA_WLAN_GET_PACKET_FILTER) {
450 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION])
451 {
452 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION"
453 " not found", __FUNCTION__);
454 return -EINVAL;
455 }
456 filterVersion = nla_get_u32(
457 tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION]);
458 ALOGV("Current version : %u", filterVersion);
459
460 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE])
461 {
462 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE"
463 " not found", __FUNCTION__);
464 return -EINVAL;
465 }
466 filterLength = nla_get_u32(
467 tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE]);
468 ALOGV("Max filter length Supported : %u", filterLength);
469 } else if (subCmd == QCA_WLAN_READ_PACKET_FILTER) {
470
471 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM])
472 {
473 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM"
474 " not found", __FUNCTION__);
475 return -EINVAL;
476 }
477 if (nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM])
478 < mfilter_packet_length)
479 {
480 ALOGE("%s: Expected packet filter length :%d but received only: %d bytes",
481 __FUNCTION__, mfilter_packet_length,
482 nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM]));
483 return -EINVAL;
484 }
485 memcpy(mfilter_packet_read_buffer,
486 nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM]),
487 mfilter_packet_length);
488 ALOGV("Filter Program length : %u", mfilter_packet_length);
489 } else {
490 ALOGE("%s: Unknown APF sub command received",
491 __FUNCTION__);
492 return -EINVAL;
493 }
494
495 }
496 break;
497 case QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE:
498 {
499 struct nlattr *tb_vendor[
500 QCA_WLAN_VENDOR_ATTR_DRV_INFO_MAX + 1];
501 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_DRV_INFO_MAX,
502 (struct nlattr *)mVendorData, mDataLen, NULL);
503
504 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE])
505 {
506 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE"
507 " not found", __FUNCTION__);
508 return -EINVAL;
509 }
510 firmware_bus_max_size = nla_get_u32(
511 tb_vendor[QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE]);
512 ALOGV("Max BUS size Supported: %d", firmware_bus_max_size);
513 }
514 break;
515 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES:
516 {
517 struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
518 nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
519 (struct nlattr *)mVendorData,mDataLen, NULL);
520
521 if (wifiParseCapabilities(tbVendor) == WIFI_SUCCESS) {
522 ALOGV("%s: GSCAN Capabilities:\n"
523 " max_ap_cache_per_scan:%d\n"
524 " max_bssid_history_entries:%d\n"
525 " max_hotlist_bssids:%d\n"
526 " max_hotlist_ssids:%d\n"
527 " max_rssi_sample_size:%d\n"
528 " max_scan_buckets:%d\n"
529 " max_scan_cache_size:%d\n"
530 " max_scan_reporting_threshold:%d\n"
531 " max_significant_wifi_change_aps:%d\n"
532 " max_number_epno_networks:%d\n"
533 " max_number_epno_networks_by_ssid:%d\n"
534 " max_number_of_white_listed_ssid:%d.",
535 __FUNCTION__, mCapa->gscan_capa.max_ap_cache_per_scan,
536 mCapa->gscan_capa.max_bssid_history_entries,
537 mCapa->gscan_capa.max_hotlist_bssids,
538 mCapa->gscan_capa.max_hotlist_ssids,
539 mCapa->gscan_capa.max_rssi_sample_size,
540 mCapa->gscan_capa.max_scan_buckets,
541 mCapa->gscan_capa.max_scan_cache_size,
542 mCapa->gscan_capa.max_scan_reporting_threshold,
543 mCapa->gscan_capa.max_significant_wifi_change_aps,
544 mCapa->gscan_capa.max_number_epno_networks,
545 mCapa->gscan_capa.max_number_epno_networks_by_ssid,
546 mCapa->gscan_capa.max_number_of_white_listed_ssid);
547
548 ALOGV("%s: Roaming Capabilities:\n"
549 " max_blacklist_size: %d\n"
550 " max_whitelist_size: %d\n",
551 __FUNCTION__, mCapa->roaming_capa.max_blacklist_size,
552 mCapa->roaming_capa.max_whitelist_size);
553 }
554 }
555 break;
556 case QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS:
557 return handle_response_usable_channels((struct nlattr *)mVendorData,
558 mDataLen);
559 case QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY:
560 {
561 wifiParseRadarHistory();
562 }
563 break;
564 case QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY:
565 {
566 struct nlattr *tb_vendor[
567 QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_MAX + 1];
568 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_MAX,
569 (struct nlattr *)mVendorData,mDataLen, NULL);
570
571 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION])
572 {
573 mInfo->sar_version = (qca_wlan_vendor_sar_version) nla_get_u32(tb_vendor[
574 QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION]);
575 }
576 ALOGV("%s: sar_version return %d", __func__, mInfo->sar_version);
577 }
578 break;
579 default :
580 ALOGE("%s: Wrong Wi-Fi HAL event received %d", __func__, mSubcmd);
581 }
582 return NL_SKIP;
583 }
584
585 /* Parses and extract capabilities results. */
wifiParseCapabilities(struct nlattr ** tbVendor)586 wifi_error WifihalGeneric::wifiParseCapabilities(struct nlattr **tbVendor)
587 {
588 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE]) {
589 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE not found",
590 __FUNCTION__);
591 return WIFI_ERROR_INVALID_ARGS;
592 }
593 mCapa->gscan_capa.max_scan_cache_size = nla_get_u32(tbVendor[
594 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE]);
595
596 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS]) {
597 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS not found",
598 __FUNCTION__);
599 return WIFI_ERROR_INVALID_ARGS;
600 }
601 mCapa->gscan_capa.max_scan_buckets = nla_get_u32(tbVendor[
602 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS]);
603
604 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN]) {
605 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN not found",
606 __FUNCTION__);
607 return WIFI_ERROR_INVALID_ARGS;
608 }
609 mCapa->gscan_capa.max_ap_cache_per_scan = nla_get_u32(tbVendor[
610 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN]);
611
612 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE]) {
613 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE not found",
614 __FUNCTION__);
615 return WIFI_ERROR_INVALID_ARGS;
616 }
617 mCapa->gscan_capa.max_rssi_sample_size = nla_get_u32(tbVendor[
618 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE]);
619
620 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD]) {
621 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD not"
622 " found", __FUNCTION__);
623 return WIFI_ERROR_INVALID_ARGS;
624 }
625 mCapa->gscan_capa.max_scan_reporting_threshold = nla_get_u32(tbVendor[
626 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD]);
627
628 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS]) {
629 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS not found",
630 __FUNCTION__);
631 return WIFI_ERROR_INVALID_ARGS;
632 }
633 mCapa->gscan_capa.max_hotlist_bssids = nla_get_u32(tbVendor[
634 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS]);
635
636 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS]
637 ) {
638 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS "
639 "not found", __FUNCTION__);
640 return WIFI_ERROR_INVALID_ARGS;
641 }
642 mCapa->gscan_capa.max_significant_wifi_change_aps = nla_get_u32(tbVendor[
643 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS]);
644
645 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES]) {
646 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES not "
647 "found", __FUNCTION__);
648 return WIFI_ERROR_INVALID_ARGS;
649 }
650 mCapa->gscan_capa.max_bssid_history_entries = nla_get_u32(tbVendor[
651 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES]);
652
653 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS]) {
654 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS not found. Set"
655 " to 0.", __FUNCTION__);
656 mCapa->gscan_capa.max_hotlist_ssids = 0;
657 } else {
658 mCapa->gscan_capa.max_hotlist_ssids = nla_get_u32(tbVendor[
659 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS]);
660 }
661
662 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS]) {
663 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS not found. Set"
664 " to 0.", __FUNCTION__);
665 mCapa->gscan_capa.max_number_epno_networks = 0;
666 } else {
667 mCapa->gscan_capa.max_number_epno_networks
668 = nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS
669 ]);
670 }
671
672 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID]) {
673 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID not "
674 "found. Set to 0.", __FUNCTION__);
675 mCapa->gscan_capa.max_number_epno_networks_by_ssid = 0;
676 } else {
677 mCapa->gscan_capa.max_number_epno_networks_by_ssid = nla_get_u32(tbVendor[
678 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID]);
679 }
680
681 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID]) {
682 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID not "
683 "found. Set to 0.", __FUNCTION__);
684 mCapa->gscan_capa.max_number_of_white_listed_ssid = 0;
685 mCapa->roaming_capa.max_whitelist_size = 0;
686 } else {
687 mCapa->gscan_capa.max_number_of_white_listed_ssid = nla_get_u32(tbVendor[
688 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID]);
689 mCapa->roaming_capa.max_whitelist_size = mCapa->gscan_capa.max_number_of_white_listed_ssid;
690 }
691
692 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID]) {
693 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX"
694 "_NUM_BLACKLIST_BSSID not found. Set to 0.", __FUNCTION__);
695 mCapa->roaming_capa.max_blacklist_size = 0;
696 } else {
697 mCapa->roaming_capa.max_blacklist_size = nla_get_u32(tbVendor[
698 QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID]);
699 }
700 return WIFI_SUCCESS;
701 }
702
wifiParseRadarHistory()703 wifi_error WifihalGeneric::wifiParseRadarHistory() {
704 {
705 // tbVendor
706 struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1];
707 int rem = 0, num_dfs_entries = 0;
708
709 if (nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX,
710 (struct nlattr *)mVendorData,mDataLen, NULL)) {
711 ALOGE("%s: nla_parse fail", __FUNCTION__);
712 return WIFI_ERROR_INVALID_ARGS;
713 }
714 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES]) {
715 ALOGE("%s: radar attr entries not present", __FUNCTION__);
716 return WIFI_ERROR_INVALID_ARGS;
717 }
718
719 // nested radar history
720 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1];
721 struct nlattr *attr;
722 static struct nla_policy
723 policy[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1] = {
724 [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ] = { .type = NLA_U32 },
725 [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP] = { .type = NLA_U64 },
726 [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED] = { .type = NLA_FLAG },
727 };
728 radar_history_result *newEntry;
729 radar_history_result *temp;
730 u32 totalEntrySize = 0;
731 u32 newEntrySize = sizeof(radar_history_result);
732
733 nla_for_each_nested(attr,
734 tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES],
735 rem) {
736 if ((num_dfs_entries ++) > MAX_NUM_RADAR_HISTORY) {
737 ALOGE("%s: exceeded max entries, drop others", __FUNCTION__);
738 break;
739 }
740 if (nla_parse_nested(tb, QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX,
741 attr, policy)) {
742 ALOGI("%s: nla_parse_nested fail", __FUNCTION__);
743 continue;
744 }
745 if (!tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ]) {
746 ALOGI("%s: radar attr freq not present", __FUNCTION__);
747 continue;
748 }
749 if (!tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP]) {
750 ALOGI("%s: radar attr timestamp not present", __FUNCTION__);
751 continue;
752 }
753
754 // realloc buffer for new entry
755 temp = (radar_history_result *) realloc(
756 mRadarResultParams.entries, totalEntrySize + newEntrySize);
757 if (temp == NULL) {
758 ALOGE("%s: failed to realloc memory", __FUNCTION__);
759 free(mRadarResultParams.entries);
760 mRadarResultParams.entries = NULL;
761 return WIFI_ERROR_OUT_OF_MEMORY;
762 }
763 mRadarResultParams.entries = temp;
764
765 newEntry = (radar_history_result *)(
766 (u8 *) mRadarResultParams.entries + totalEntrySize);
767 memset(newEntry, 0, newEntrySize);
768 totalEntrySize += newEntrySize;
769
770 // save to current radar entry
771 newEntry->freq = nla_get_u32(
772 tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ]);
773 newEntry->clock_boottime = nla_get_u64(
774 tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP]);
775 newEntry->radar_detected = false;
776 if (tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED]) {
777 newEntry->radar_detected = nla_get_flag(
778 tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED]);
779 }
780 mRadarResultParams.num_entries ++;
781
782 ALOGI("Radar history: freq:%d boottime: %" PRId64 " detected:%d",
783 newEntry->freq,
784 newEntry->clock_boottime,
785 newEntry->radar_detected);
786 }
787 }
788
789 return WIFI_SUCCESS;
790 }
791
792
getResponseparams(feature_set * pset)793 void WifihalGeneric::getResponseparams(feature_set *pset)
794 {
795 *pset = mSet;
796 }
797
getDriverFeatures(features_info * pfeatures)798 void WifihalGeneric::getDriverFeatures(features_info *pfeatures)
799 {
800 if (!pfeatures)
801 return;
802
803 if (mDriverFeatures.flags != NULL) {
804 pfeatures->flags = (u8 *)malloc(mDriverFeatures.flags_len);
805 if (pfeatures->flags) {
806 memcpy(pfeatures->flags, mDriverFeatures.flags,
807 mDriverFeatures.flags_len);
808 pfeatures->flags_len = mDriverFeatures.flags_len;
809 return;
810 }
811 }
812
813 pfeatures->flags_len = 0;
814 pfeatures->flags = NULL;
815 }
816
setMaxSetSize(int set_size_max)817 void WifihalGeneric::setMaxSetSize(int set_size_max) {
818 mSetSizeMax = set_size_max;
819 }
820
setConcurrencySet(feature_set set[])821 void WifihalGeneric::setConcurrencySet(feature_set set[]) {
822 mConcurrencySet = set;
823 }
824
setSizePtr(int * set_size)825 void WifihalGeneric::setSizePtr(int *set_size) {
826 mSetSizePtr = set_size;
827 }
828
getFilterVersion()829 int WifihalGeneric::getFilterVersion() {
830 return filterVersion;
831 }
832
getFilterLength()833 int WifihalGeneric::getFilterLength() {
834 return filterLength;
835 }
setPacketBufferParams(u8 * host_packet_buffer,int packet_length)836 void WifihalGeneric::setPacketBufferParams(u8 *host_packet_buffer, int packet_length) {
837 mfilter_packet_read_buffer = host_packet_buffer;
838 mfilter_packet_length = packet_length;
839 }
840
getBusSize()841 int WifihalGeneric::getBusSize() {
842 return firmware_bus_max_size;
843 }
844
set_channels_buff(wifi_usable_channel * channels)845 void WifihalGeneric::set_channels_buff(wifi_usable_channel* channels)
846 {
847 channel_buff = channels;
848 memset(channel_buff, 0, sizeof(wifi_usable_channel) * mSetSizeMax);
849 }
850
get_results_size(void)851 u32 WifihalGeneric::get_results_size(void)
852 {
853 return res_size;
854 }
855
wifiGetCapabilities(wifi_interface_handle handle)856 wifi_error WifihalGeneric::wifiGetCapabilities(wifi_interface_handle handle)
857 {
858 wifi_error ret;
859 struct nlattr *nlData;
860 interface_info *ifaceInfo = getIfaceInfo(handle);
861
862 /* Create the NL message. */
863 ret = create();
864 if (ret != WIFI_SUCCESS) {
865 ALOGE("%s: Failed to create NL message, Error:%d", __FUNCTION__, ret);
866 return ret;
867 }
868
869 /* Set the interface Id of the message. */
870 ret = set_iface_id(ifaceInfo->name);
871 if (ret != WIFI_SUCCESS) {
872 ALOGE("%s: Failed to set interface Id of message, Error:%d", __FUNCTION__, ret);
873 return ret;
874 }
875
876 /* Add the vendor specific attributes for the NL command. */
877 nlData = attr_start(NL80211_ATTR_VENDOR_DATA);
878 if (!nlData)
879 return WIFI_ERROR_OUT_OF_MEMORY;
880
881 ret = put_u32(QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, mId);
882 if (ret != WIFI_SUCCESS) {
883 ALOGE("%s: Failed to add request_ID to NL command, Error:%d", __FUNCTION__, ret);
884 return ret;
885 }
886
887 attr_end(nlData);
888
889 ret = requestResponse();
890 if (ret != WIFI_SUCCESS)
891 ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret);
892
893 return ret;
894 }
895
copyCachedRadarHistory(radar_history_result * resultBuf,int resultBufSize,int * numResults)896 wifi_error WifihalGeneric::copyCachedRadarHistory(
897 radar_history_result *resultBuf, int resultBufSize, int *numResults) {
898 *numResults = 0;
899
900 if (mRadarResultParams.entries) {
901 radar_history_result *sEntry = NULL;
902 radar_history_result *tEntry = NULL;
903 u32 offset = 0;
904 int i;
905
906 for (i = 0; i < mRadarResultParams.num_entries; i ++) {
907 if (resultBufSize < (offset + sizeof(radar_history_result))) {
908 break;
909 }
910
911 sEntry = (radar_history_result *)(
912 (u8 *) mRadarResultParams.entries + offset);
913 tEntry = (radar_history_result *)(
914 (u8 *) resultBuf + offset);
915 memcpy(tEntry, sEntry, sizeof(radar_history_result));
916 (*numResults) += 1;
917 offset += sizeof(radar_history_result);
918 }
919 }
920
921 return WIFI_SUCCESS;
922 }
923
freeCachedRadarHistory()924 void WifihalGeneric::freeCachedRadarHistory() {
925 if (mRadarResultParams.entries) {
926 free(mRadarResultParams.entries);
927 mRadarResultParams.entries = NULL;
928 mRadarResultParams.num_entries = 0;
929 }
930 }
931
getSarVersion(wifi_interface_handle handle)932 wifi_error WifihalGeneric::getSarVersion(wifi_interface_handle handle)
933 {
934 wifi_error ret;
935 interface_info *ifaceInfo = getIfaceInfo(handle);
936
937
938 /* Create the NL message. */
939 ret = create();
940 if (ret != WIFI_SUCCESS) {
941 ALOGE("%s: Failed to create NL message, Error:%d", __FUNCTION__, ret);
942 return ret;
943 }
944
945 /* Set the interface Id of the message. */
946 ret = set_iface_id(ifaceInfo->name);
947 if (ret != WIFI_SUCCESS) {
948 ALOGE("%s: Failed to set interface Id of message, Error:%d", __FUNCTION__, ret);
949 return ret;
950 }
951
952 ret = requestResponse();
953 if (ret != WIFI_SUCCESS)
954 ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret);
955
956 return ret;
957 }
958
959