Merge changes from topic "radio_mode_cbs_hidl"
* changes:
wifi(implementation): Invoke radio mode change callbacks
wifi(implementation): Conversion functions for radio mode change
wifi(implementation): WifiLegacyHal interface for radio mode change
wifi(interface): Add callbacks for indicating radio mode changes
diff --git a/wifi/1.2/Android.bp b/wifi/1.2/Android.bp
index 100b36b..f41324e 100644
--- a/wifi/1.2/Android.bp
+++ b/wifi/1.2/Android.bp
@@ -10,6 +10,7 @@
"types.hal",
"IWifi.hal",
"IWifiChip.hal",
+ "IWifiChipEventCallback.hal",
"IWifiNanIface.hal",
"IWifiNanIfaceEventCallback.hal",
],
diff --git a/wifi/1.2/IWifiChip.hal b/wifi/1.2/IWifiChip.hal
index 72cbf81..d336a33 100644
--- a/wifi/1.2/IWifiChip.hal
+++ b/wifi/1.2/IWifiChip.hal
@@ -16,7 +16,9 @@
package android.hardware.wifi@1.2;
+import @1.0::WifiStatus;
import @1.1::IWifiChip;
+import IWifiChipEventCallback;
/**
* Interface that represents a chip that must be configured as a single unit.
@@ -24,4 +26,18 @@
* to perform operations like NAN, RTT, etc.
*/
interface IWifiChip extends @1.1::IWifiChip {
+ /**
+ * Requests notifications of significant events on this chip. Multiple calls
+ * to this must register multiple callbacks each of which must receive all
+ * events.
+ *
+ * @param callback An instance of the |IWifiChipEventCallback| HIDL interface
+ * object.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+ */
+ registerEventCallback_1_2(IWifiChipEventCallback callback)
+ generates (WifiStatus status);
};
diff --git a/wifi/1.2/IWifiChipEventCallback.hal b/wifi/1.2/IWifiChipEventCallback.hal
new file mode 100644
index 0000000..5d2e7e9
--- /dev/null
+++ b/wifi/1.2/IWifiChipEventCallback.hal
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.2;
+
+import @1.0::IWifiChipEventCallback;
+import @1.0::WifiBand;
+
+/**
+ * Wifi chip event callbacks.
+ */
+interface IWifiChipEventCallback extends @1.0::IWifiChipEventCallback {
+ /**
+ * Struct describing the state of each iface operating on the radio chain
+ * (hardware MAC) on the device.
+ */
+ struct IfaceInfo {
+ /** Name of the interface (For ex: "wlan0"). */
+ string name;
+ /** Wifi channel on which this interface is operating. */
+ uint32_t channel;
+ };
+
+ /**
+ * Struct describing the state of each hardware radio chain (hardware MAC)
+ * on the device.
+ */
+ struct RadioModeInfo {
+ /**
+ * Identifier for this radio chain. This is vendor dependent & used
+ * only for debugging purposes.
+ */
+ uint32_t radioId;
+ /**
+ * List of bands on which this radio chain is operating.
+ * Can be one of:
+ * a) WifiBand.BAND_24GHZ => 2.4Ghz.
+ * b) WifiBand.BAND_5GHZ => 5Ghz.
+ * c) WifiBand.BAND_24GHZ_5GHZ = 2.4Ghz + 5Ghz (Radio is time sharing
+ * across the 2 bands).
+ */
+ WifiBand bandInfo;
+ /** List of interfaces on this radio chain (hardware MAC). */
+ vec<IfaceInfo> ifaceInfos;
+ };
+
+ /**
+ * Asynchronous callback indicating a radio mode change.
+ * Radio mode change could be a result of:
+ * a) Bringing up concurrent interfaces (For ex: STA + AP).
+ * b) Change in operating band of one of the concurrent interfaces (For ex:
+ * STA connection moved from 2.4G to 5G)
+ *
+ * @param radioModeInfos List of RadioModeInfo structures for each
+ * radio chain (hardware MAC) on the device.
+ */
+ oneway onRadioModeChange(vec<RadioModeInfo> radioModeInfos);
+};
diff --git a/wifi/1.2/default/Android.mk b/wifi/1.2/default/Android.mk
index 8d0262b..978cf63 100644
--- a/wifi/1.2/default/Android.mk
+++ b/wifi/1.2/default/Android.mk
@@ -94,6 +94,7 @@
LOCAL_MODULE := android.hardware.wifi@1.0-service-tests
LOCAL_PROPRIETARY_MODULE := true
LOCAL_SRC_FILES := \
+ tests/hidl_struct_util_unit_tests.cpp \
tests/main.cpp \
tests/mock_wifi_feature_flags.cpp \
tests/mock_wifi_legacy_hal.cpp \
diff --git a/wifi/1.2/default/hidl_struct_util.cpp b/wifi/1.2/default/hidl_struct_util.cpp
index f87828c..b1c609e 100644
--- a/wifi/1.2/default/hidl_struct_util.cpp
+++ b/wifi/1.2/default/hidl_struct_util.cpp
@@ -266,6 +266,57 @@
CHECK(false);
}
+bool convertLegacyWifiMacInfoToHidl(
+ const legacy_hal::WifiMacInfo& legacy_mac_info,
+ IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) {
+ if (!hidl_radio_mode_info) {
+ return false;
+ }
+ *hidl_radio_mode_info = {};
+
+ hidl_radio_mode_info->radioId = legacy_mac_info.wlan_mac_id;
+ // Convert from bitmask of bands in the legacy HAL to enum value in
+ // the HIDL interface.
+ if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_5GHZ;
+ } else {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_UNSPECIFIED;
+ }
+ std::vector<IWifiChipEventCallback::IfaceInfo> iface_info_vec;
+ for (const auto& legacy_iface_info : legacy_mac_info.iface_infos) {
+ IWifiChipEventCallback::IfaceInfo iface_info;
+ iface_info.name = legacy_iface_info.name;
+ iface_info.channel = legacy_iface_info.channel;
+ iface_info_vec.push_back(iface_info);
+ }
+ hidl_radio_mode_info->ifaceInfos = iface_info_vec;
+ return true;
+}
+
+bool convertLegacyWifiMacInfosToHidl(
+ const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+ std::vector<IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos) {
+ if (!hidl_radio_mode_infos) {
+ return false;
+ }
+ *hidl_radio_mode_infos = {};
+
+ for (const auto& legacy_mac_info : legacy_mac_infos) {
+ IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info;
+ if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info,
+ &hidl_radio_mode_info)) {
+ return false;
+ }
+ hidl_radio_mode_infos->push_back(hidl_radio_mode_info);
+ }
+ return true;
+}
+
bool convertLegacyFeaturesToHidlStaCapabilities(
uint32_t legacy_feature_set, uint32_t legacy_logger_feature_set,
uint32_t* hidl_caps) {
diff --git a/wifi/1.2/default/hidl_struct_util.h b/wifi/1.2/default/hidl_struct_util.h
index 1208afd..ce4bb81 100644
--- a/wifi/1.2/default/hidl_struct_util.h
+++ b/wifi/1.2/default/hidl_struct_util.h
@@ -22,6 +22,7 @@
#include <android/hardware/wifi/1.0/IWifiChip.h>
#include <android/hardware/wifi/1.0/types.h>
#include <android/hardware/wifi/1.1/IWifiChip.h>
+#include <android/hardware/wifi/1.2/IWifiChipEventCallback.h>
#include <android/hardware/wifi/1.2/types.h>
#include "wifi_legacy_hal.h"
@@ -55,6 +56,9 @@
WifiDebugHostWakeReasonStats* hidl_stats);
legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
V1_1::IWifiChip::TxPowerScenario hidl_scenario);
+bool convertLegacyWifiMacInfosToHidl(
+ const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+ std::vector<IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos);
// STA iface conversion methods.
bool convertLegacyFeaturesToHidlStaCapabilities(
diff --git a/wifi/1.2/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.2/default/tests/hidl_struct_util_unit_tests.cpp
new file mode 100644
index 0000000..1d6e9e4
--- /dev/null
+++ b/wifi/1.2/default/tests/hidl_struct_util_unit_tests.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#undef NAN
+#include "hidl_struct_util.h"
+
+using testing::Test;
+
+namespace {
+constexpr uint32_t kMacId1 = 1;
+constexpr uint32_t kMacId2 = 2;
+constexpr uint32_t kIfaceChannel1 = 3;
+constexpr uint32_t kIfaceChannel2 = 5;
+constexpr char kIfaceName1[] = "wlan0";
+constexpr char kIfaceName2[] = "wlan1";
+} // namespace
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+
+class HidlStructUtilTest : public Test {};
+
+TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) {
+ std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
+ legacy_hal::WifiMacInfo legacy_mac_info1 = {
+ .wlan_mac_id = kMacId1,
+ .mac_band =
+ legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND};
+ legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1,
+ .channel = kIfaceChannel1};
+ legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2,
+ .channel = kIfaceChannel2};
+ legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
+ legacy_mac_info1.iface_infos.push_back(legacy_iface_info2);
+ legacy_mac_infos.push_back(legacy_mac_info1);
+
+ std::vector<IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
+ ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(
+ legacy_mac_infos, &hidl_radio_mode_infos));
+
+ ASSERT_EQ(1u, hidl_radio_mode_infos.size());
+ auto hidl_radio_mode_info1 = hidl_radio_mode_infos[0];
+ EXPECT_EQ(legacy_mac_info1.wlan_mac_id, hidl_radio_mode_info1.radioId);
+ EXPECT_EQ(WifiBand::BAND_24GHZ_5GHZ, hidl_radio_mode_info1.bandInfo);
+ ASSERT_EQ(2u, hidl_radio_mode_info1.ifaceInfos.size());
+ auto hidl_iface_info1 = hidl_radio_mode_info1.ifaceInfos[0];
+ EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name);
+ EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel),
+ hidl_iface_info1.channel);
+ auto hidl_iface_info2 = hidl_radio_mode_info1.ifaceInfos[1];
+ EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name);
+ EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel),
+ hidl_iface_info2.channel);
+}
+
+TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) {
+ std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
+ legacy_hal::WifiMacInfo legacy_mac_info1 = {
+ .wlan_mac_id = kMacId1, .mac_band = legacy_hal::WLAN_MAC_5_0_BAND};
+ legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1,
+ .channel = kIfaceChannel1};
+ legacy_hal::WifiMacInfo legacy_mac_info2 = {
+ .wlan_mac_id = kMacId2, .mac_band = legacy_hal::WLAN_MAC_2_4_BAND};
+ legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2,
+ .channel = kIfaceChannel2};
+ legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
+ legacy_mac_infos.push_back(legacy_mac_info1);
+ legacy_mac_info2.iface_infos.push_back(legacy_iface_info2);
+ legacy_mac_infos.push_back(legacy_mac_info2);
+
+ std::vector<IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
+ ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(
+ legacy_mac_infos, &hidl_radio_mode_infos));
+
+ ASSERT_EQ(2u, hidl_radio_mode_infos.size());
+
+ // Find mac info 1.
+ const auto hidl_radio_mode_info1 = std::find_if(
+ hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
+ [&legacy_mac_info1](const IWifiChipEventCallback::RadioModeInfo& x) {
+ return x.radioId == legacy_mac_info1.wlan_mac_id;
+ });
+ ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1);
+ EXPECT_EQ(WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo);
+ ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size());
+ auto hidl_iface_info1 = hidl_radio_mode_info1->ifaceInfos[0];
+ EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name);
+ EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel),
+ hidl_iface_info1.channel);
+
+ // Find mac info 2.
+ const auto hidl_radio_mode_info2 = std::find_if(
+ hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
+ [&legacy_mac_info2](const IWifiChipEventCallback::RadioModeInfo& x) {
+ return x.radioId == legacy_mac_info2.wlan_mac_id;
+ });
+ ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2);
+ EXPECT_EQ(WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo);
+ ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size());
+ auto hidl_iface_info2 = hidl_radio_mode_info2->ifaceInfos[0];
+ EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name);
+ EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel),
+ hidl_iface_info2.channel);
+}
+} // namespace implementation
+} // namespace V1_2
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index bc3404a..38301e9 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -306,7 +306,7 @@
}
Return<void> WifiChip::registerEventCallback(
- const sp<IWifiChipEventCallback>& event_callback,
+ const sp<V1_0::IWifiChipEventCallback>& event_callback,
registerEventCallback_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
&WifiChip::registerEventCallbackInternal,
@@ -520,6 +520,14 @@
hidl_status_cb);
}
+Return<void> WifiChip::registerEventCallback_1_2(
+ const sp<IWifiChipEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::registerEventCallbackInternal_1_2,
+ hidl_status_cb, event_callback);
+}
+
Return<void> WifiChip::debug(const hidl_handle& handle,
const hidl_vec<hidl_string>&) {
if (handle != nullptr && handle->numFds >= 1) {
@@ -556,11 +564,9 @@
}
WifiStatus WifiChip::registerEventCallbackInternal(
- const sp<IWifiChipEventCallback>& event_callback) {
- if (!event_cb_handler_.addCallback(event_callback)) {
- return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
- }
- return createWifiStatus(WifiStatusCode::SUCCESS);
+ const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
+ // Deprecated support for this callback.
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
@@ -997,6 +1003,14 @@
return createWifiStatusFromLegacyError(legacy_status);
}
+WifiStatus WifiChip::registerEventCallbackInternal_1_2(
+ const sp<IWifiChipEventCallback>& event_callback) {
+ if (!event_cb_handler_.addCallback(event_callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
WifiStatus WifiChip::handleChipConfiguration(
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
ChipModeId mode_id) {
@@ -1030,6 +1044,13 @@
<< legacyErrorToString(legacy_status);
return createWifiStatusFromLegacyError(legacy_status);
}
+ // Every time the HAL is restarted, we need to register the
+ // radio mode change callback.
+ WifiStatus status = registerRadioModeChangeCallback();
+ if (status.code != WifiStatusCode::SUCCESS) {
+ // This probably is not a critical failure?
+ LOG(ERROR) << "Failed to register radio mode change callback";
+ }
return createWifiStatus(WifiStatusCode::SUCCESS);
}
@@ -1073,6 +1094,36 @@
return createWifiStatusFromLegacyError(legacy_status);
}
+WifiStatus WifiChip::registerRadioModeChangeCallback() {
+ android::wp<WifiChip> weak_ptr_this(this);
+ const auto& on_radio_mode_change_callback =
+ [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ std::vector<IWifiChipEventCallback::RadioModeInfo>
+ hidl_radio_mode_infos;
+ if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(
+ mac_infos, &hidl_radio_mode_infos)) {
+ LOG(ERROR) << "Error converting wifi mac info";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onRadioModeChange(hidl_radio_mode_infos)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke onRadioModeChange"
+ << " callback on: " << toString(callback);
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
+ getWlan0IfaceName(), on_radio_mode_change_callback);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
void WifiChip::populateModes() {
// The chip combination supported for current devices is fixed.
// They can be one of the following based on device features:
diff --git a/wifi/1.2/default/wifi_chip.h b/wifi/1.2/default/wifi_chip.h
index 4ffa8da..24a5486 100644
--- a/wifi/1.2/default/wifi_chip.h
+++ b/wifi/1.2/default/wifi_chip.h
@@ -74,7 +74,7 @@
// HIDL methods exposed.
Return<void> getId(getId_cb hidl_status_cb) override;
Return<void> registerEventCallback(
- const sp<IWifiChipEventCallback>& event_callback,
+ const sp<V1_0::IWifiChipEventCallback>& event_callback,
registerEventCallback_cb hidl_status_cb) override;
Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
Return<void> getAvailableModes(
@@ -138,6 +138,9 @@
resetTxPowerScenario_cb hidl_status_cb) override;
Return<void> debug(const hidl_handle& handle,
const hidl_vec<hidl_string>& options) override;
+ Return<void> registerEventCallback_1_2(
+ const sp<IWifiChipEventCallback>& event_callback,
+ registerEventCallback_1_2_cb hidl_status_cb) override;
private:
void invalidateAndRemoveAllIfaces();
@@ -145,7 +148,7 @@
// Corresponding worker functions for the HIDL methods.
std::pair<WifiStatus, ChipId> getIdInternal();
WifiStatus registerEventCallbackInternal(
- const sp<IWifiChipEventCallback>& event_callback);
+ const sp<V1_0::IWifiChipEventCallback>& event_callback);
std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
std::pair<WifiStatus, std::vector<ChipMode>> getAvailableModesInternal();
WifiStatus configureChipInternal(
@@ -192,10 +195,13 @@
WifiStatus enableDebugErrorAlertsInternal(bool enable);
WifiStatus selectTxPowerScenarioInternal(TxPowerScenario scenario);
WifiStatus resetTxPowerScenarioInternal();
+ WifiStatus registerEventCallbackInternal_1_2(
+ const sp<IWifiChipEventCallback>& event_callback);
WifiStatus handleChipConfiguration(
std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
WifiStatus registerDebugRingBufferCallback();
+ WifiStatus registerRadioModeChangeCallback();
void populateModes();
std::vector<IWifiChip::ChipIfaceCombination>
diff --git a/wifi/1.2/default/wifi_legacy_hal.cpp b/wifi/1.2/default/wifi_legacy_hal.cpp
index 9abe514..5f40d50 100644
--- a/wifi/1.2/default/wifi_legacy_hal.cpp
+++ b/wifi/1.2/default/wifi_legacy_hal.cpp
@@ -148,6 +148,17 @@
}
}
+// Callback to be invoked for radio mode change indication.
+std::function<void(wifi_request_id, uint32_t, wifi_mac_info*)>
+ on_radio_mode_change_internal_callback;
+void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs,
+ wifi_mac_info* mac_infos) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_radio_mode_change_internal_callback) {
+ on_radio_mode_change_internal_callback(id, num_macs, mac_infos);
+ }
+}
+
// Callback to be invoked for rtt results results.
std::function<void(wifi_request_id, unsigned num_results,
wifi_rtt_result* rtt_results[])>
@@ -937,6 +948,41 @@
0, getIfaceHandle(iface_name));
}
+wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
+ const std::string& iface_name,
+ const on_radio_mode_change_callback& on_user_change_callback) {
+ if (on_radio_mode_change_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_radio_mode_change_internal_callback = [on_user_change_callback](
+ wifi_request_id /* id */,
+ uint32_t num_macs,
+ wifi_mac_info* mac_infos_arr) {
+ if (num_macs > 0 && mac_infos_arr) {
+ std::vector<WifiMacInfo> mac_infos_vec;
+ for (uint32_t i = 0; i < num_macs; i++) {
+ WifiMacInfo mac_info;
+ mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id;
+ mac_info.mac_band = mac_infos_arr[i].mac_band;
+ for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) {
+ WifiIfaceInfo iface_info;
+ iface_info.name = mac_infos_arr[i].iface_info[j].iface_name;
+ iface_info.channel = mac_infos_arr[i].iface_info[j].channel;
+ mac_info.iface_infos.push_back(iface_info);
+ }
+ mac_infos_vec.push_back(mac_info);
+ }
+ on_user_change_callback(mac_infos_vec);
+ }
+ };
+ wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler(
+ 0, getIfaceHandle(iface_name), {onAsyncRadioModeChange});
+ if (status != WIFI_SUCCESS) {
+ on_radio_mode_change_internal_callback = nullptr;
+ }
+ return status;
+}
+
wifi_error WifiLegacyHal::startRttRangeRequest(
const std::string& iface_name, wifi_request_id id,
const std::vector<wifi_rtt_config>& rtt_configs,
@@ -1324,6 +1370,7 @@
on_rssi_threshold_breached_internal_callback = nullptr;
on_ring_buffer_data_internal_callback = nullptr;
on_error_alert_internal_callback = nullptr;
+ on_radio_mode_change_internal_callback = nullptr;
on_rtt_results_internal_callback = nullptr;
on_nan_notify_response_user_callback = nullptr;
on_nan_event_publish_terminated_user_callback = nullptr;
diff --git a/wifi/1.2/default/wifi_legacy_hal.h b/wifi/1.2/default/wifi_legacy_hal.h
index da88f6b..bd68bcd 100644
--- a/wifi/1.2/default/wifi_legacy_hal.h
+++ b/wifi/1.2/default/wifi_legacy_hal.h
@@ -132,6 +132,26 @@
// Callback for alerts.
using on_error_alert_callback =
std::function<void(int32_t, const std::vector<uint8_t>&)>;
+
+// Struct for the mac info from the legacy HAL. This is a cleaner version
+// of the |wifi_mac_info| & |wifi_iface_info|.
+typedef struct {
+ std::string name;
+ wifi_channel channel;
+} WifiIfaceInfo;
+
+typedef struct {
+ uint32_t wlan_mac_id;
+ /* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */
+ uint32_t mac_band;
+ /* Represents the connected Wi-Fi interfaces associated with each MAC */
+ std::vector<WifiIfaceInfo> iface_infos;
+} WifiMacInfo;
+
+// Callback for radio mode change
+using on_radio_mode_change_callback =
+ std::function<void(const std::vector<WifiMacInfo>&)>;
+
/**
* Class that encapsulates all legacy HAL interactions.
* This class manages the lifetime of the event loop thread used by legacy HAL.
@@ -253,6 +273,10 @@
const on_error_alert_callback& on_alert_callback);
wifi_error deregisterErrorAlertCallbackHandler(
const std::string& iface_name);
+ // Radio mode functions.
+ wifi_error registerRadioModeChangeCallbackHandler(
+ const std::string& iface_name,
+ const on_radio_mode_change_callback& on_user_change_callback);
// RTT functions.
wifi_error startRttRangeRequest(
const std::string& iface_name, wifi_request_id id,
diff --git a/wifi/1.2/default/wifi_legacy_hal_stubs.cpp b/wifi/1.2/default/wifi_legacy_hal_stubs.cpp
index 28972cb..2ee2aa2 100644
--- a/wifi/1.2/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.2/default/wifi_legacy_hal_stubs.cpp
@@ -134,6 +134,7 @@
populateStubFor(&hal_fn->wifi_configure_roaming);
populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
+ populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler);
return true;
}
} // namespace legacy_hal