From 5780336dd2d84006e6de8e3331b320bb8c2aba83 Mon Sep 17 00:00:00 2001 From: Khanjan Desai Date: Fri, 17 Apr 2020 16:20:10 +0800 Subject: WifiHAl:Create separate create/delete virtual iface functions The function wifi_add_or_remove_iface was taking care for creation and deletion of virtual Iface. Added new separate functions that will perform create and delete operations instead of one single API. Bug: 153852667 Bug: 154279995 Test: Pass wifi aware tests of CtsVerifier. CRs-Fixed: 2633140 Change-Id: I3c175b1f5a59c6d022b2db51cfc72b48582ec3cf --- qcwcn/wifi_hal/common.h | 4 ++ qcwcn/wifi_hal/wifi_hal.cpp | 5 ++ qcwcn/wifi_hal/wificonfig.cpp | 121 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) diff --git a/qcwcn/wifi_hal/common.h b/qcwcn/wifi_hal/common.h index c545ca1..43b03ce 100644 --- a/qcwcn/wifi_hal/common.h +++ b/qcwcn/wifi_hal/common.h @@ -208,6 +208,10 @@ wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle i wifi_error wifi_set_radio_mode_change_handler(wifi_request_id id, wifi_interface_handle iface, wifi_radio_mode_change_handler eh); wifi_error mapKernelErrortoWifiHalError(int kern_err); +void wifi_cleanup_dynamic_ifaces(wifi_handle handle); +wifi_error wifi_virtual_interface_create(wifi_handle handle, const char* ifname, + wifi_interface_type iface_type); +wifi_error wifi_virtual_interface_delete(wifi_handle handle, const char* ifname); // some common macros #define min(x, y) ((x) < (y) ? (x) : (y)) diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp index 2bf7937..7b85099 100644 --- a/qcwcn/wifi_hal/wifi_hal.cpp +++ b/qcwcn/wifi_hal/wifi_hal.cpp @@ -571,6 +571,8 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) { fn->wifi_select_tx_power_scenario = wifi_select_tx_power_scenario; fn->wifi_reset_tx_power_scenario = wifi_reset_tx_power_scenario; fn->wifi_set_radio_mode_change_handler = wifi_set_radio_mode_change_handler; + fn->wifi_virtual_interface_create = wifi_virtual_interface_create; + fn->wifi_virtual_interface_delete = wifi_virtual_interface_delete; fn->wifi_set_latency_mode = wifi_set_latency_mode; fn->wifi_set_thermal_mitigation_mode = wifi_set_thermal_mitigation_mode; @@ -1042,6 +1044,9 @@ void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler) hal_info *info = getHalInfo(handle); info->cleaned_up_handler = handler; info->clean_up = true; + // Remove the dynamically created interface during wifi cleanup. + wifi_cleanup_dynamic_ifaces(handle); + TEMP_FAILURE_RETRY(write(info->exit_sockets[0], "E", 1)); ALOGI("Sent msg on exit sock to unblock poll()"); diff --git a/qcwcn/wifi_hal/wificonfig.cpp b/qcwcn/wifi_hal/wificonfig.cpp index 7590f62..8ab296a 100644 --- a/qcwcn/wifi_hal/wificonfig.cpp +++ b/qcwcn/wifi_hal/wificonfig.cpp @@ -33,6 +33,9 @@ #include #include #include +#include +#include +#include #include "wificonfigcommand.h" /* Implementation of the API functions exposed in wifi_config.h */ @@ -788,3 +791,121 @@ out: return res; } +static std::vector added_ifaces; + +static bool is_dynamic_interface(const char * ifname) +{ + for (const auto& iface : added_ifaces) { + if (iface == std::string(ifname)) + return true; + } + return false; +} + +void wifi_cleanup_dynamic_ifaces(wifi_handle handle) +{ + int len = added_ifaces.size(); + while (len--) { + wifi_virtual_interface_delete(handle, added_ifaces.front().c_str()); + } + added_ifaces.clear(); // could be redundent. But to be on safe side. +} + +wifi_error wifi_virtual_interface_create(wifi_handle handle, + const char* ifname, + wifi_interface_type iface_type) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + u32 wlan0_id = if_nametoindex("wlan0"); + if (!handle || !wlan0_id) { + ALOGE("%s: Error wifi_handle NULL or wlan0 not present", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ALOGD("%s: ifname=%s create", __FUNCTION__, ifname); + // Do not create interface if already exist. + if (if_nametoindex(ifname)) + return WIFI_SUCCESS; + + wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nl80211_iftype type; + switch(iface_type) { + case WIFI_INTERFACE_TYPE_STA: /* IfaceType:STA */ + type = NL80211_IFTYPE_STATION; + break; + case WIFI_INTERFACE_TYPE_AP: /* IfaceType:AP */ + type = NL80211_IFTYPE_AP; + break; + case WIFI_INTERFACE_TYPE_P2P: /* IfaceType:P2P */ + type = NL80211_IFTYPE_P2P_DEVICE; + break; + case WIFI_INTERFACE_TYPE_NAN: /* IfaceType:NAN */ + type = NL80211_IFTYPE_NAN; + break; + default: + ALOGE("%s: Wrong interface type %u", __FUNCTION__, iface_type); + ret = WIFI_ERROR_UNKNOWN; + goto done; + break; + } + wifiConfigCommand->create_generic(NL80211_CMD_NEW_INTERFACE); + wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, wlan0_id); + wifiConfigCommand->put_string(NL80211_ATTR_IFNAME, ifname); + wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE, type); + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret); + } + // Update dynamic interface list + added_ifaces.push_back(std::string(ifname)); + +done: + delete wifiConfigCommand; + return ret; +} + +wifi_error wifi_virtual_interface_delete(wifi_handle handle, + const char* ifname) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + u32 wlan0_id = if_nametoindex("wlan0"); + + if (!handle || !wlan0_id) { + ALOGE("%s: Error wifi_handle NULL or wlan0 not present", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ALOGD("%s: ifname=%s delete", __FUNCTION__, ifname); + if (if_nametoindex(ifname) && !is_dynamic_interface(ifname)) { + // Do not remove interface if it was not added dynamically. + return WIFI_SUCCESS; + } + wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE); + wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname)); + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret); + } + // Update dynamic interface list + added_ifaces.erase(std::remove(added_ifaces.begin(), added_ifaces.end(), std::string(ifname)), + added_ifaces.end()); + + delete wifiConfigCommand; + return ret; +} -- cgit v1.2.3