Skip to content
Snippets Groups Projects
Commit 5780336d authored by Khanjan Desai's avatar Khanjan Desai Committed by Victor Hsu
Browse files

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
parent fe979945
No related merge requests found
......@@ -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))
......
......@@ -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()");
......
......@@ -33,6 +33,9 @@
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <net/if.h>
#include <vector>
#include "wificonfigcommand.h"
/* Implementation of the API functions exposed in wifi_config.h */
......@@ -788,3 +791,121 @@ out:
return res;
}
static std::vector<std::string> 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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment