summaryrefslogtreecommitdiff
path: root/qcwcn/wifi_hal/wificonfig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qcwcn/wifi_hal/wificonfig.cpp')
-rw-r--r--qcwcn/wifi_hal/wificonfig.cpp121
1 files changed, 121 insertions, 0 deletions
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 <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;
+}