summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMir Ali <mir-khizer.ali@broadcom.com>2020-12-28 17:45:06 +0530
committerAhmed ElArabawy <arabawy@google.com>2021-01-07 14:01:01 -0800
commitdab88eb17d19c06035a729ecd81017204cffab06 (patch)
tree4cd98f237663fab3fdf81ad253148cc69c086d4a
parent8fc82e3d2f5867d16dc82f24a533657bbd3f669a (diff)
downloadwlan-dab88eb17d19c06035a729ecd81017204cffab06.tar.gz
Add support for MultiSta Primary Connection and Usecase functionality
The changes include support for 1. Setting Primary connection interface 2. Setting multista use case Bug: 168555306 Test: Validated on Hikey960 with Android S. Signed-off-by: Mir Ali <mir-khizer.ali@broadcom.com> Change-Id: Ibdc3a9797f7c7acbec7b9299cee76333d20357f5
-rwxr-xr-xbcmdhd/wifi_hal/common.h2
-rwxr-xr-xbcmdhd/wifi_hal/wifi_hal.cpp162
2 files changed, 164 insertions, 0 deletions
diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h
index 008d1c8..29b6797 100755
--- a/bcmdhd/wifi_hal/common.h
+++ b/bcmdhd/wifi_hal/common.h
@@ -165,6 +165,8 @@ typedef enum {
WIFI_SUBCMD_FW_ROAM_POLICY, /* 0x1019 */
WIFI_SUBCMD_ROAM_CAPABILITY, /* 0x101a */
WIFI_SUBCMD_SET_LATENCY_MODE, /* 0x101b */
+ WIFI_SUBCMD_SET_MULTISTA_PRIMARY_CONNECTION, /* 0x101c */
+ WIFI_SUBCMD_SET_MULTISTA_USE_CASE, /* 0x101d */
GSCAN_SUBCMD_MAX,
diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp
index 5d74e23..cb91526 100755
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -157,6 +157,18 @@ enum wifi_chavoid_attr {
CHAVOID_ATTRIBUTE_MAX
};
+enum wifi_multista_attr {
+ MULTISTA_ATTRIBUTE_PRIM_CONN_IFACE,
+ MULTISTA_ATTRIBUTE_USE_CASE,
+ /* Add more attributes here */
+ MULTISTA_ATTRIBUTE_MAX
+};
+
+enum multista_request_type {
+ SET_PRIMARY_CONNECTION,
+ SET_USE_CASE
+};
+
/* Initialize/Cleanup */
void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
@@ -295,6 +307,8 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
fn->wifi_twt_info_frame_request = twt_info_frame_request;
fn->wifi_twt_get_stats = twt_get_stats;
fn->wifi_twt_clear_stats = twt_clear_stats;
+ fn->wifi_multi_sta_set_primary_connection = wifi_multi_sta_set_primary_connection;
+ fn->wifi_multi_sta_set_use_case = wifi_multi_sta_set_use_case;
return WIFI_SUCCESS;
}
@@ -1640,6 +1654,29 @@ wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t
return WIFI_SUCCESS;
}
+wifi_interface_handle wifi_get_iface_handle(wifi_handle handle, char *name)
+{
+ char buf[EVENT_BUF_SIZE];
+ wifi_interface_handle *ifaceHandles;
+ int numIfaceHandles;
+ wifi_interface_handle ifHandle;
+
+ wifi_error res = wifi_get_ifaces((wifi_handle)handle, &numIfaceHandles, &ifaceHandles);
+ if (res < 0) {
+ return NULL;
+ }
+ for (int i = 0; i < numIfaceHandles; i++) {
+ if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
+ if (strcmp(buf, name) == 0) {
+ ALOGI("found interface %s\n", buf);
+ ifHandle = ifaceHandles[i];
+ return ifHandle;
+ }
+ }
+ }
+ return NULL;
+}
+
wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
{
GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1);
@@ -2429,3 +2466,128 @@ wifi_error wifi_virtual_interface_delete(wifi_handle handle, const char* ifname)
return ret;
}
/////////////////////////////////////////////////////////////////////////////
+
+class MultiStaConfig : public WifiCommand {
+ wifi_multi_sta_use_case mUseCase;
+ int mReqType;
+
+public:
+ MultiStaConfig(wifi_interface_handle handle)
+ : WifiCommand("MultiStaConfig", handle, 0), mReqType(SET_PRIMARY_CONNECTION)
+ {
+ }
+ MultiStaConfig(wifi_interface_handle handle, wifi_multi_sta_use_case use_case)
+ : WifiCommand("MultiStaConfig", handle, 0), mUseCase(use_case), mReqType(SET_USE_CASE)
+ {
+ mUseCase = use_case;
+ }
+
+ int createRequest(WifiRequest& request) {
+ if (mReqType == SET_PRIMARY_CONNECTION) {
+ ALOGI("\n%s: MultiSta set primary connection\n", __FUNCTION__);
+ return createSetPrimaryConnectionRequest(request);
+ } else if (mReqType == SET_USE_CASE) {
+ ALOGI("\n%s: MultiSta set use case\n", __FUNCTION__);
+ return createSetUsecaseRequest(request);
+ } else {
+ ALOGE("\n%s Unknown MultiSta request\n", __FUNCTION__);
+ return WIFI_ERROR_NOT_SUPPORTED;
+ }
+ return WIFI_SUCCESS;
+ }
+
+ int createSetPrimaryConnectionRequest(WifiRequest& request) {
+ int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_MULTISTA_PRIMARY_CONNECTION);
+ if (result < 0) {
+ return result;
+ }
+
+ nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+ request.attr_end(data);
+
+ return result;
+ }
+
+ int createSetUsecaseRequest(WifiRequest& request) {
+ int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_MULTISTA_USE_CASE);
+ if (result < 0) {
+ return result;
+ }
+
+ nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+ result = request.put_u32(MULTISTA_ATTRIBUTE_USE_CASE, mUseCase);
+ if (result < 0) {
+ ALOGE("failed to put MULTISTA_ATTRIBUTE_USE_CASE = %d; result = %d", mUseCase, result);
+ goto exit;
+ }
+
+exit: request.attr_end(data);
+ return result;
+ }
+
+ int start() {
+ WifiRequest request(familyId(), ifaceId());
+ int result = createRequest(request);
+ if (result < 0) {
+ return result;
+ }
+ result = requestResponse(request);
+ if (result < 0) {
+ ALOGI("Request Response failed for MultiSta, result = %d", result);
+ return result;
+ }
+ ALOGI("Done!");
+ return result;
+ }
+protected:
+ virtual int handleResponse(WifiEvent& reply) {
+ ALOGD("Request complete!");
+ /* Nothing to do on response! */
+ return NL_SKIP;
+ }
+};
+
+wifi_error wifi_multi_sta_set_primary_connection(wifi_handle handle, wifi_interface_handle iface)
+{
+ wifi_error ret = WIFI_SUCCESS;
+
+ if (!handle || !iface) {
+ ALOGE("%s: Error wifi_handle NULL or invalid wifi interface handle\n", __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ALOGD("Setting Multista primary connection = %p\n", iface);
+ MultiStaConfig *cmd = new MultiStaConfig(iface);
+ NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+ ret = (wifi_error)cmd->start();
+ cmd->releaseRef();
+ return ret;
+}
+
+wifi_error wifi_multi_sta_set_use_case(wifi_handle handle, wifi_multi_sta_use_case use_case)
+{
+ int numIfaceHandles = 0;
+ wifi_error ret = WIFI_SUCCESS;
+ wifi_interface_handle *ifaceHandles = NULL;
+ wifi_interface_handle wlan0Handle;
+
+ if (!handle) {
+ ALOGE("%s: Error wifi_handle NULL\n", __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ if (!(use_case >= WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY &&
+ use_case <= WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED)) {
+ ALOGE("%s: Invalid multi_sta usecase %d\n", __FUNCTION__, use_case);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
+ ALOGD("Setting Multista usecase = %d\n", use_case);
+ MultiStaConfig *cmd = new MultiStaConfig(wlan0Handle, use_case);
+ NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+ ret = (wifi_error)cmd->start();
+ cmd->releaseRef();
+ return ret;
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////