summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Jeon <dennis.jeon@broadcom.com>2021-02-26 18:09:30 +0900
committerRoger Wang <wangroger@google.com>2021-03-11 10:16:27 +0800
commit3e158f4047de0d4761d184746f59fa50de2b516a (patch)
treef95618deb18c7986a46660262ffa4ead4f15096c
parentc3ab6d3f6b836bad5fca96f351bb88834b18ba51 (diff)
downloadwlan-3e158f4047de0d4761d184746f59fa50de2b516a.tar.gz
Add support for reporting usable channel
Added wifi_hal layer implementation to support wifi_get_usable_channel() API. Bug: 178813134 Test: Validated on Hikey960 with Android S. Change-Id: I10e0628e8e3a59daa01eb72542ddf5eac0b74c1d
-rwxr-xr-xbcmdhd/wifi_hal/common.h18
-rwxr-xr-xbcmdhd/wifi_hal/wifi_hal.cpp147
2 files changed, 159 insertions, 6 deletions
diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h
index e83f6be..df653a3 100755
--- a/bcmdhd/wifi_hal/common.h
+++ b/bcmdhd/wifi_hal/common.h
@@ -119,17 +119,21 @@ typedef enum {
ANDROID_NL80211_SUBCMD_CHAVOID_RANGE_START = 0x2100,
ANDROID_NL80211_SUBCMD_CHAVOID_RANGE_END = 0x211F,
- /* define all TWT related commands between 0x2140 and 0x214F */
- ANDROID_NL80211_SUBCMD_TWT_START = 0x2140,
- ANDROID_NL80211_SUBCMD_TWT_END = 0x214F,
+ /* define all OTA Download related commands between 0x2120 and 0x212F */
+ ANDROID_NL80211_SUBCMD_OTA_DOWNLOAD_START = 0x2120,
+ ANDROID_NL80211_SUBCMD_OTA_DOWNLOAD_END = 0x212F,
/* define all VOIP mode config related commands between 0x2130 and 0x213F */
ANDROID_NL80211_SUBCMD_VIOP_MODE_START = 0x2130,
ANDROID_NL80211_SUBCMD_VIOP_MODE_END = 0x213F,
- /* define all OTA Download related commands between 0x2120 and 0x212F */
- ANDROID_NL80211_SUBCMD_OTA_DOWNLOAD_START = 0x2120,
- ANDROID_NL80211_SUBCMD_OTA_DOWNLOAD_END = 0x212F,
+ /* define all TWT related commands between 0x2140 and 0x214F */
+ ANDROID_NL80211_SUBCMD_TWT_START = 0x2140,
+ ANDROID_NL80211_SUBCMD_TWT_END = 0x214F,
+
+ /* define all Usable Channel related commands between 0x2150 and 0x215F */
+ ANDROID_NL80211_SUBCMD_USABLE_CHANNEL_START = 0x2150,
+ ANDROID_NL80211_SUBCMD_USABLE_CHANNEL_END = 0x215F,
/* This is reserved for future usage */
@@ -219,6 +223,8 @@ typedef enum {
WIFI_SUBCMD_GET_OTA_CURRUNT_INFO = ANDROID_NL80211_SUBCMD_OTA_DOWNLOAD_START,
WIFI_SUBCMD_OTA_UPDATE,
+ WIFI_SUBCMD_USABLE_CHANNEL = ANDROID_NL80211_SUBCMD_USABLE_CHANNEL_START,
+
} WIFI_SUB_COMMAND;
typedef enum {
diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp
index 5cf0fcc..6907d99 100755
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -91,6 +91,8 @@ static wifi_error wifi_read_packet_filter(wifi_interface_handle handle, u32 src_
static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
u32 *version, u32 *max_len);
static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, u8 enable);
+static wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, u32 iface_mode_mask,
+ u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels);
static void wifi_cleanup_dynamic_ifaces(wifi_handle handle);
typedef enum wifi_attr {
@@ -161,6 +163,17 @@ enum wifi_chavoid_attr {
CHAVOID_ATTRIBUTE_MAX
};
+enum wifi_usable_channel_attributes {
+ USABLECHAN_ATTRIBUTE_INVALID = 0,
+ USABLECHAN_ATTRIBUTE_BAND = 1,
+ USABLECHAN_ATTRIBUTE_IFACE = 2,
+ USABLECHAN_ATTRIBUTE_FILTER = 3,
+ USABLECHAN_ATTRIBUTE_MAX_SIZE = 4,
+ USABLECHAN_ATTRIBUTE_SIZE = 5,
+ USABLECHAN_ATTRIBUTE_CHANNELS = 6,
+ USABLECHAN_ATTRIBUTE_MAX
+};
+
enum wifi_multista_attr {
MULTISTA_ATTRIBUTE_PRIM_CONN_IFACE,
MULTISTA_ATTRIBUTE_USE_CASE,
@@ -315,6 +328,7 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
fn->wifi_multi_sta_set_use_case = wifi_multi_sta_set_use_case;
fn->wifi_set_voip_mode = wifi_set_voip_mode;
fn->wifi_set_dtim_config = wifi_set_dtim_config;
+ fn->wifi_get_usable_channels = wifi_get_usable_channels;
return WIFI_SUCCESS;
}
@@ -2708,3 +2722,136 @@ wifi_error wifi_set_dtim_config(wifi_interface_handle handle, u32 multiplier)
SetDtimConfigCommand command(handle, multiplier);
return (wifi_error) command.requestResponse();
}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+class UsableChannelCommand : public WifiCommand {
+
+private:
+ u32 mBandMask;
+ u32 mIfaceModeMask;
+ u32 mFilterMask;
+ u32 mMaxSize;
+ u32* mSize;
+ wifi_usable_channel* mChannels;
+
+public:
+ UsableChannelCommand(wifi_interface_handle handle, u32 band_mask, u32 iface_mode_mask,
+ u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels)
+ : WifiCommand("UsableChannelCommand", handle, 0),
+ mBandMask(band_mask), mIfaceModeMask(iface_mode_mask),
+ mFilterMask(filter_mask), mMaxSize(max_size),
+ mSize(size), mChannels(channels)
+ {
+ }
+
+ int createRequest(WifiRequest& request) {
+ createUsableChannelRequest(request);
+ return WIFI_SUCCESS;
+ }
+
+ int createUsableChannelRequest(WifiRequest& request) {
+ int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_USABLE_CHANNEL);
+ if (result < 0) {
+ ALOGE("Failed to create UsableChannel request; result = %d", result);
+ return result;
+ }
+
+ nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+ result = request.put_u32(USABLECHAN_ATTRIBUTE_BAND, mBandMask);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("Failed to put log level; result = %d", result);
+ return result;
+ }
+ result = request.put_u32(USABLECHAN_ATTRIBUTE_IFACE, mIfaceModeMask);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("Failed to put ring flags; result = %d", result);
+ return result;
+ }
+ result = request.put_u32(USABLECHAN_ATTRIBUTE_FILTER, mFilterMask);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("Failed to put usablechan filter; result = %d", result);
+ return result;
+ }
+ result = request.put_u32(USABLECHAN_ATTRIBUTE_MAX_SIZE, mMaxSize);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("Failed to put usablechan max_size; result = %d", result);
+ return result;
+ }
+ request.attr_end(data);
+
+ return WIFI_SUCCESS;
+ }
+
+ int start() {
+ WifiRequest request(familyId(), ifaceId());
+ int result = createRequest(request);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("failed to create request; result = %d", result);
+ return result;
+ }
+
+ result = requestResponse(request);
+ if (result != WIFI_SUCCESS) {
+ ALOGE("failed to set scanning mac OUI; result = %d", result);
+ }
+
+ return result;
+ }
+
+ virtual int handleResponse(WifiEvent& reply) {
+ ALOGD("In DebugCommand::handleResponse");
+
+ if (reply.get_cmd() != NL80211_CMD_VENDOR) {
+ ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+ return NL_SKIP;
+ }
+
+ nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
+ int len = reply.get_vendor_data_len();
+ wifi_usable_channel *channels(mChannels);
+
+ if (vendor_data == NULL || len == 0) {
+ ALOGE("No Debug data found");
+ return NL_SKIP;
+ }
+
+ nl_iterator it(vendor_data);
+ if (it.get_type() == USABLECHAN_ATTRIBUTE_SIZE) {
+ *mSize = it.get_u32();
+ } else {
+ ALOGE("Unknown attribute: %d expecting %d",
+ it.get_type(), USABLECHAN_ATTRIBUTE_SIZE);
+ return NL_SKIP;
+ }
+
+ it.next();
+ if (it.get_type() == USABLECHAN_ATTRIBUTE_CHANNELS) {
+ memcpy(channels, it.get_data(), sizeof(wifi_usable_channel) * *mSize);
+ } else {
+ ALOGE("Unknown attribute: %d expecting %d",
+ it.get_type(), USABLECHAN_ATTRIBUTE_SIZE);
+ return NL_SKIP;
+ }
+
+ return NL_OK;
+ }
+
+ virtual int handleEvent(WifiEvent& event) {
+ /* NO events! */
+ return NL_SKIP;
+ }
+};
+
+wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, u32 iface_mode_mask,
+ u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels)
+{
+ int numIfaceHandles = 0;
+ wifi_interface_handle *ifaceHandles = NULL;
+ wifi_interface_handle wlan0Handle;
+
+ wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
+ UsableChannelCommand command(wlan0Handle, band_mask, iface_mode_mask,
+ filter_mask, max_size, size, channels);
+ return (wifi_error)command.start();
+}