wpa_supplicant(hidl): Implement ANQP query requests
These will only initiate the ANQP query requests. The callbacks for
these will need some changes in the wpa_supplicant core and will be made
in a separate CL.
Bug: 31116047
Test: Compiles
Change-Id: Ia2d2b4d99da5eefe476748192280f35733174861
diff --git a/wpa_supplicant/hidl/hidl_manager.h b/wpa_supplicant/hidl/hidl_manager.h
index 9acaa00..0b569e2 100644
--- a/wpa_supplicant/hidl/hidl_manager.h
+++ b/wpa_supplicant/hidl/hidl_manager.h
@@ -315,6 +315,53 @@
"State value mismatch");
static_assert(
+ static_cast<uint32_t>(ISupplicantStaIface::AnqpInfoId::VENUE_NAME) ==
+ ANQP_VENUE_NAME,
+ "ANQP ID value mismatch");
+static_assert(
+ static_cast<uint32_t>(
+ ISupplicantStaIface::AnqpInfoId::ROAMING_CONSORTIUM) ==
+ ANQP_ROAMING_CONSORTIUM,
+ "ANQP ID value mismatch");
+static_assert(
+ static_cast<uint32_t>(ISupplicantStaIface::AnqpInfoId::NAI_REALM) ==
+ ANQP_NAI_REALM,
+ "ANQP ID value mismatch");
+static_assert(
+ static_cast<uint32_t>(
+ ISupplicantStaIface::AnqpInfoId::IP_ADDR_TYPE_AVAILABILITY) ==
+ ANQP_IP_ADDR_TYPE_AVAILABILITY,
+ "ANQP ID value mismatch");
+static_assert(
+ static_cast<uint32_t>(
+ ISupplicantStaIface::AnqpInfoId::ANQP_3GPP_CELLULAR_NETWORK) ==
+ ANQP_3GPP_CELLULAR_NETWORK,
+ "ANQP ID value mismatch");
+static_assert(
+ static_cast<uint32_t>(ISupplicantStaIface::AnqpInfoId::DOMAIN_NAME) ==
+ ANQP_DOMAIN_NAME,
+ "ANQP ID value mismatch");
+static_assert(
+ static_cast<uint32_t>(
+ ISupplicantStaIface::Hs20AnqpSubtypes::OPERATOR_FRIENDLY_NAME) ==
+ HS20_STYPE_OPERATOR_FRIENDLY_NAME,
+ "HS Subtype value mismatch");
+static_assert(
+ static_cast<uint32_t>(ISupplicantStaIface::Hs20AnqpSubtypes::WAN_METRICS) ==
+ HS20_STYPE_WAN_METRICS,
+ "HS Subtype value mismatch");
+static_assert(
+ static_cast<uint32_t>(
+ ISupplicantStaIface::Hs20AnqpSubtypes::CONNECTION_CAPABILITY) ==
+ HS20_STYPE_CONNECTION_CAPABILITY,
+ "HS Subtype value mismatch");
+static_assert(
+ static_cast<uint32_t>(
+ ISupplicantStaIface::Hs20AnqpSubtypes::OSU_PROVIDERS_LIST) ==
+ HS20_STYPE_OSU_PROVIDERS_LIST,
+ "HS Subtype value mismatch");
+
+static_assert(
static_cast<uint32_t>(
ISupplicantP2pIface::GroupCapabilityMask::GROUP_OWNER) ==
P2P_GROUP_CAPAB_GROUP_OWNER,
diff --git a/wpa_supplicant/hidl/sta_iface.cpp b/wpa_supplicant/hidl/sta_iface.cpp
index 4379dd5..a60267d 100644
--- a/wpa_supplicant/hidl/sta_iface.cpp
+++ b/wpa_supplicant/hidl/sta_iface.cpp
@@ -11,6 +11,16 @@
#include "hidl_return_util.h"
#include "sta_iface.h"
+extern "C" {
+#include "gas_query.h"
+#include "interworking.h"
+#include "hs20_supplicant.h"
+}
+
+namespace {
+constexpr uint32_t kMaxAnqpElems = 100;
+} // namespace
+
namespace android {
namespace hardware {
namespace wifi {
@@ -345,14 +355,46 @@
const std::vector<ISupplicantStaIface::AnqpInfoId> &info_elements,
const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types)
{
- // TODO: Add implementation.
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ if (info_elements.size() > kMaxAnqpElems) {
+ return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
+ }
+ uint16_t *info_elems_buf = static_cast<uint16_t *>(
+ os_malloc(sizeof(uint16_t) * info_elements.size()));
+ if (!info_elems_buf) {
+ return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
+ }
+ uint32_t num_info_elems = 0;
+ for (const auto &info_element : info_elements) {
+ info_elems_buf[num_info_elems++] =
+ static_cast<std::underlying_type<
+ ISupplicantStaIface::AnqpInfoId>::type>(info_element);
+ }
+ uint32_t sub_types_bitmask = 0;
+ for (const auto &type : sub_types) {
+ sub_types_bitmask |= BIT(
+ static_cast<std::underlying_type<
+ ISupplicantStaIface::Hs20AnqpSubtypes>::type>(type));
+ }
+ if (anqp_send_req(
+ wpa_s, mac_address.data(), info_elems_buf, num_info_elems,
+ sub_types_bitmask, false)) {
+ return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
+ }
return {SupplicantStatusCode::SUCCESS, ""};
}
SupplicantStatus StaIface::initiateHs20IconQueryInternal(
const std::array<uint8_t, 6> &mac_address, const std::string &file_name)
{
- // TODO: Add implementation.
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ wpa_s->fetch_osu_icon_in_progress = 0;
+ if (hs20_anqp_send_req(
+ wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
+ reinterpret_cast<const uint8_t *>(file_name.c_str()),
+ file_name.size(), true)) {
+ return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
+ }
return {SupplicantStatusCode::SUCCESS, ""};
}
@@ -364,8 +406,7 @@
*/
wpa_supplicant *StaIface::retrieveIfacePtr()
{
- return wpa_supplicant_get_iface(
- (struct wpa_global *)wpa_global_, ifname_.c_str());
+ return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
}
} // namespace implementation
diff --git a/wpa_supplicant/hidl/sta_iface.h b/wpa_supplicant/hidl/sta_iface.h
index a4177aa..01b2b5e 100644
--- a/wpa_supplicant/hidl/sta_iface.h
+++ b/wpa_supplicant/hidl/sta_iface.h
@@ -133,7 +133,7 @@
// Reference to the global wpa_struct. This is assumed to be valid for
// the lifetime of the process.
- const struct wpa_global* wpa_global_;
+ struct wpa_global* wpa_global_;
// Name of the iface this hidl object controls
const std::string ifname_;
bool is_valid_;