aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Biren <gbiren@google.com>2022-05-05 19:36:43 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-05-05 19:36:43 +0000
commit5f523c76c4cc69e62e3c4d3713a00116aecc28fb (patch)
tree94112c418fdd2a3742abc0fe756060c66db8a163
parentcfc3487ddb3839cec413a016721570725805a987 (diff)
parent9d7720d3ef7dba6e4d41ddba4f20af947fbbd5be (diff)
downloadwpa_supplicant_8-5f523c76c4cc69e62e3c4d3713a00116aecc28fb.tar.gz
Merge "wpa_supplicant: Add changes to support QoS policy AIDL APIs" into tm-dev am: 9d7720d3ef
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/wpa_supplicant_8/+/18169962 Change-Id: Idfd352adde3bebb25cb8e8377e9ff43697c84636 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--wpa_supplicant/aidl/aidl.cpp32
-rw-r--r--wpa_supplicant/aidl/aidl.h8
-rw-r--r--wpa_supplicant/aidl/aidl_manager.cpp131
-rw-r--r--wpa_supplicant/aidl/aidl_manager.h4
-rw-r--r--wpa_supplicant/aidl/sta_iface.cpp42
-rw-r--r--wpa_supplicant/notify.c17
-rw-r--r--wpa_supplicant/notify.h3
-rw-r--r--wpa_supplicant/robust_av.c54
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h15
9 files changed, 286 insertions, 20 deletions
diff --git a/wpa_supplicant/aidl/aidl.cpp b/wpa_supplicant/aidl/aidl.cpp
index eb384971..1add3df4 100644
--- a/wpa_supplicant/aidl/aidl.cpp
+++ b/wpa_supplicant/aidl/aidl.cpp
@@ -1001,3 +1001,35 @@ void wpas_aidl_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
AuxiliarySupplicantEventCode::OPEN_SSL_FAILURE,
reason_string);
}
+
+void wpas_aidl_notify_qos_policy_reset(
+ struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s)
+ return;
+ wpa_printf(
+ MSG_DEBUG, "Notifying Qos Policy Reset");
+
+ AidlManager *aidl_manager = AidlManager::getInstance();
+ if (!aidl_manager)
+ return;
+
+ aidl_manager->notifyQosPolicyReset(wpa_s);
+}
+
+void wpas_aidl_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
+ struct dscp_policy_data *policies, int num_policies)
+{
+ if (!wpa_s || !policies)
+ return;
+
+ wpa_printf(
+ MSG_DEBUG, "Notifying Qos Policy Request");
+
+ AidlManager *aidl_manager = AidlManager::getInstance();
+ if (!aidl_manager)
+ return;
+
+ aidl_manager->notifyQosPolicyRequest(wpa_s, policies, num_policies);
+}
+
diff --git a/wpa_supplicant/aidl/aidl.h b/wpa_supplicant/aidl/aidl.h
index fcd462b0..d9ab7bd2 100644
--- a/wpa_supplicant/aidl/aidl.h
+++ b/wpa_supplicant/aidl/aidl.h
@@ -139,6 +139,9 @@ extern "C"
const char *reason_string);
void wpas_aidl_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
const char *reason_string);
+ void wpas_aidl_notify_qos_policy_reset(struct wpa_supplicant *wpa_s);
+ void wpas_aidl_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
+ struct dscp_policy_data *policies, int num_policies);
#else // CONFIG_CTRL_IFACE_AIDL
static inline int wpas_aidl_register_interface(struct wpa_supplicant *wpa_s)
{
@@ -308,6 +311,11 @@ void wpas_aidl_notify_ssid_temp_disabled(struct wpa_supplicant *wpa_s,
void wpas_aidl_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
const char *reason_string)
{}
+static void wpas_aidl_notify_qos_policy_reset(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
+ struct dscp_policy_data *policies,
+ int num_policies)
+{}
#endif // CONFIG_CTRL_IFACE_AIDL
#ifdef _cplusplus
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index 91245702..ac7b8e84 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -15,6 +15,7 @@
#include "misc_utils.h"
#include <android/binder_process.h>
#include <android/binder_manager.h>
+#include <aidl/android/hardware/wifi/supplicant/IpVersion.h>
extern "C" {
#include "scan.h"
@@ -2331,6 +2332,136 @@ void AidlManager::callWithEachStaNetworkCallback(
ifname, network_id, method, sta_network_callbacks_map_);
}
+void AidlManager::notifyQosPolicyReset(
+ struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s)
+ return;
+
+ callWithEachStaIfaceCallback(
+ misc_utils::charBufToString(wpa_s->ifname), std::bind(
+ &ISupplicantStaIfaceCallback::onQosPolicyReset,
+ std::placeholders::_1));
+}
+
+void AidlManager::notifyQosPolicyRequest(struct wpa_supplicant *wpa_s,
+ struct dscp_policy_data *policies, int num_policies)
+{
+ if (!wpa_s || !policies)
+ return;
+
+ std::vector<QosPolicyData> qosPolicyData;
+ uint32_t mask = 0;
+
+ for (int num = 0; num < num_policies; num++) {
+ QosPolicyData policy;
+ QosPolicyClassifierParams classifier_params;
+ QosPolicyClassifierParamsMask classifier_param_mask;
+ bool ip_ver4 = false;
+
+ if (policies[num].type4_param.ip_version == 4) {
+ classifier_params.ipVersion = IpVersion::VERSION_4;
+ ip_ver4 = true;
+ } else {
+ classifier_params.ipVersion = IpVersion::VERSION_6;
+ ip_ver4 = false;
+ }
+
+ // classifier_mask parameters are defined in IEEE Std 802.11-2020, Table 9-170
+ if (policies[num].type4_param.classifier_mask & BIT(1)) {
+ mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::SRC_IP);
+ if (ip_ver4) {
+ classifier_params.srcIp =
+ byteArrToVec((const uint8_t *)
+ &policies[num].type4_param.ip_params.v4.src_ip, 4);
+ } else {
+ classifier_params.srcIp =
+ byteArrToVec((const uint8_t *)
+ &policies[num].type4_param.ip_params.v6.src_ip, 16);
+ }
+ }
+ if (policies[num].type4_param.classifier_mask & BIT(2)) {
+ mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::DST_IP);
+ if (ip_ver4){
+ classifier_params.dstIp =
+ byteArrToVec((const uint8_t *)
+ &policies[num].type4_param.ip_params.v4.dst_ip, 4);
+ } else {
+ classifier_params.dstIp =
+ byteArrToVec((const uint8_t *)
+ &policies[num].type4_param.ip_params.v6.dst_ip, 16);
+ }
+ }
+ if (policies[num].type4_param.classifier_mask & BIT(3)) {
+ mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::SRC_PORT);
+ if (ip_ver4){
+ classifier_params.srcPort =
+ policies[num].type4_param.ip_params.v4.src_port;
+ } else {
+ classifier_params.srcPort =
+ policies[num].type4_param.ip_params.v6.src_port;
+ }
+ }
+
+ if (policies[num].type4_param.classifier_mask & BIT(4)) {
+ mask |= static_cast<uint32_t>(
+ QosPolicyClassifierParamsMask::DST_PORT_RANGE);
+ if (ip_ver4) {
+ classifier_params.dstPortRange.startPort =
+ policies[num].type4_param.ip_params.v4.dst_port;
+ classifier_params.dstPortRange.endPort =
+ policies[num].type4_param.ip_params.v4.dst_port;
+ } else {
+ classifier_params.dstPortRange.startPort =
+ policies[num].type4_param.ip_params.v6.dst_port;
+ classifier_params.dstPortRange.endPort =
+ policies[num].type4_param.ip_params.v6.dst_port;
+ }
+ } else if (policies[num].port_range_info) {
+ mask |= static_cast<uint32_t>(
+ QosPolicyClassifierParamsMask::DST_PORT_RANGE);
+ classifier_params.dstPortRange.startPort = policies[num].start_port;
+ classifier_params.dstPortRange.endPort = policies[num].end_port;
+ }
+ if (policies[num].type4_param.classifier_mask & BIT(6)) {
+ mask |= static_cast<uint32_t>(
+ QosPolicyClassifierParamsMask::PROTOCOL_NEXT_HEADER);
+ if (ip_ver4) {
+ classifier_params.protocolNextHdr = static_cast<ProtocolNextHeader>(
+ policies[num].type4_param.ip_params.v4.protocol);
+ } else {
+ classifier_params.protocolNextHdr = static_cast<ProtocolNextHeader>(
+ policies[num].type4_param.ip_params.v6.next_header);
+ }
+ }
+ if (policies[num].type4_param.classifier_mask & BIT(7)) {
+ mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::FLOW_LABEL);
+ classifier_params.flowLabelIpv6 =
+ byteArrToVec(policies[num].type4_param.ip_params.v6.flow_label, 3);
+ }
+ if (policies[num].domain_name_len != 0) {
+ mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::DOMAIN_NAME);
+ classifier_params.domainName =
+ misc_utils::charBufToString(
+ reinterpret_cast<const char *>(policies[num].domain_name));
+ }
+
+ classifier_params.classifierParamMask =
+ static_cast<QosPolicyClassifierParamsMask>(mask);
+ policy.policyId = policies[num].policy_id;
+ policy.requestType = static_cast<QosPolicyRequestType>(policies[num].req_type);
+ policy.dscp = policies[num].dscp;
+ policy.classifierParams = classifier_params;
+
+ qosPolicyData.push_back(policy);
+ }
+
+ callWithEachStaIfaceCallback(
+ misc_utils::charBufToString(wpa_s->ifname), std::bind(
+ &ISupplicantStaIfaceCallback::onQosPolicyRequest,
+ std::placeholders::_1, wpa_s->dscp_req_dialog_token, qosPolicyData));
+}
+
} // namespace supplicant
} // namespace wifi
} // namespace hardware
diff --git a/wpa_supplicant/aidl/aidl_manager.h b/wpa_supplicant/aidl/aidl_manager.h
index 15f8e28b..6acacf56 100644
--- a/wpa_supplicant/aidl/aidl_manager.h
+++ b/wpa_supplicant/aidl/aidl_manager.h
@@ -153,6 +153,10 @@ public:
void notifyAuxiliaryEvent(struct wpa_supplicant *wpa_s,
AuxiliarySupplicantEventCode event_code,
const char *reason_string);
+ void notifyQosPolicyReset(struct wpa_supplicant *wpa_s);
+ void notifyQosPolicyRequest(struct wpa_supplicant *wpa_s,
+ struct dscp_policy_data *policies,
+ int num_policies);
// Methods called from aidl objects.
void notifyExtRadioWorkStart(struct wpa_supplicant *wpa_s, uint32_t id);
diff --git a/wpa_supplicant/aidl/sta_iface.cpp b/wpa_supplicant/aidl/sta_iface.cpp
index b4fbb242..7a07cc18 100644
--- a/wpa_supplicant/aidl/sta_iface.cpp
+++ b/wpa_supplicant/aidl/sta_iface.cpp
@@ -1871,6 +1871,8 @@ StaIface::getKeyMgmtCapabilitiesInternal()
ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabledInternal(bool enable)
{
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ wpa_s->enable_dscp_policy_capa = enable ? 1 : 0;
return ndk::ScopedAStatus::ok();
}
@@ -1878,11 +1880,51 @@ ndk::ScopedAStatus StaIface::sendQosPolicyResponseInternal(
int32_t qos_policy_request_id, bool more_policies,
const std::vector<QosPolicyStatus>& qos_policy_status_list)
{
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ struct dscp_resp_data resp_data;
+ int num_policies = qos_policy_status_list.size();
+
+ memset(&resp_data, 0, sizeof(resp_data));
+
+ resp_data.more = more_policies ? 1 : 0;
+ resp_data.policy = (struct dscp_policy_status *) malloc(
+ sizeof(struct dscp_policy_status) * num_policies);
+ if (num_policies && !resp_data.policy){
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
+
+ resp_data.solicited = true;
+ wpa_s->dscp_req_dialog_token = qos_policy_request_id;
+
+ for (int i = 0; i < num_policies; i++) {
+ resp_data.policy[i].id = qos_policy_status_list.at(i).policyId;
+ resp_data.policy[i].status =
+ static_cast<uint8_t>(qos_policy_status_list.at(i).status);
+ }
+ resp_data.num_policies = num_policies;
+
+ if (wpas_send_dscp_response(wpa_s, &resp_data)) {
+ free(resp_data.policy);
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
+
+ free(resp_data.policy);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus StaIface::removeAllQosPoliciesInternal()
{
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ struct dscp_resp_data resp_data;
+
+ memset(&resp_data, 0, sizeof(resp_data));
+ resp_data.reset = true;
+ resp_data.solicited = false;
+ wpa_s->dscp_req_dialog_token = 0;
+
+ if (wpas_send_dscp_response(wpa_s, &resp_data)) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
return ndk::ScopedAStatus::ok();
}
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 72c62601..4c305186 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1304,3 +1304,20 @@ void wpas_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
{
wpas_aidl_notify_open_ssl_failure(wpa_s, reason_string);
}
+
+void wpas_notify_qos_policy_reset(struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s)
+ return;
+
+ wpas_aidl_notify_qos_policy_reset(wpa_s);
+}
+
+void wpas_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
+ struct dscp_policy_data *policies, int num_policies)
+{
+ if (!wpa_s || !policies)
+ return;
+
+ wpas_aidl_notify_qos_policy_request(wpa_s, policies, num_policies);
+}
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 80357495..f7000171 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -214,5 +214,8 @@ void wpas_notify_ssid_temp_disabled(struct wpa_supplicant *wpa_s,
const char *reason_string);
void wpas_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
const char *reason_string);
+void wpas_notify_qos_policy_reset(struct wpa_supplicant *wpa_s);
+void wpas_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
+ struct dscp_policy_data *policies, int num_policies);
#endif /* NOTIFY_H */
diff --git a/wpa_supplicant/robust_av.c b/wpa_supplicant/robust_av.c
index 770c8fca..61107972 100644
--- a/wpa_supplicant/robust_av.c
+++ b/wpa_supplicant/robust_av.c
@@ -14,6 +14,7 @@
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "bss.h"
+#include "notify.h"
#define SCS_RESP_TIMEOUT 1
@@ -843,22 +844,6 @@ static int write_ipv6_info(char *pos, int total_len,
}
-struct dscp_policy_data {
- u8 policy_id;
- u8 req_type;
- u8 dscp;
- bool dscp_info;
- const u8 *frame_classifier;
- u8 frame_classifier_len;
- struct type4_params type4_param;
- const u8 *domain_name;
- u8 domain_name_len;
- u16 start_port;
- u16 end_port;
- bool port_range_info;
-};
-
-
static int set_frame_classifier_type4_ipv4(struct dscp_policy_data *policy)
{
u8 classifier_mask;
@@ -1062,7 +1047,7 @@ static bool dscp_valid_domain_name(const char *str)
}
-static void wpas_add_dscp_policy(struct wpa_supplicant *wpa_s,
+static int wpas_add_dscp_policy(struct wpa_supplicant *wpa_s,
struct dscp_policy_data *policy)
{
int ip_ver = 0, res;
@@ -1147,10 +1132,11 @@ static void wpas_add_dscp_policy(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
"add policy_id=%u dscp=%u ip_version=%d%s",
policy->policy_id, policy->dscp, ip_ver, policy_str);
- return;
+ return 0;
fail:
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "reject policy_id=%u",
policy->policy_id);
+ return -1;
}
@@ -1231,6 +1217,9 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
const u8 *qos_ie, *attr;
int more, reset;
+ struct dscp_policy_data *policies = NULL, *policies_temp;
+ int num_dscp_policies = 0;
+
if (!wpa_s->enable_dscp_policy_capa) {
wpa_printf(MSG_ERROR,
"QM: Ignore DSCP Policy frame since the capability is not enabled");
@@ -1276,6 +1265,9 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
more = buf[2] & DSCP_POLICY_CTRL_MORE;
reset = buf[2] & DSCP_POLICY_CTRL_RESET;
+ if (reset)
+ wpas_notify_qos_policy_reset(wpa_s);
+
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_start%s%s",
reset ? " clear_all" : "", more ? " more" : "");
@@ -1283,6 +1275,7 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
rem_len = len - 3;
while (rem_len > 2) {
struct dscp_policy_data policy;
+ int res = 0;
int rem_attrs_len, ie_len;
ie_len = 2 + qos_ie[1];
@@ -1318,16 +1311,37 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
}
if (policy.req_type == DSCP_POLICY_REQ_ADD)
- wpas_add_dscp_policy(wpa_s, &policy);
+ res = wpas_add_dscp_policy(wpa_s, &policy);
else if (policy.req_type == DSCP_POLICY_REQ_REMOVE)
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
"remove policy_id=%u", policy.policy_id);
- else
+ else {
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
"reject policy_id=%u", policy.policy_id);
+ res = -1;
+ }
+
+ if (res)
+ continue;
+
+ policies_temp = os_realloc(policies,
+ (num_dscp_policies + 1) *
+ sizeof(struct dscp_policy_data));
+ if (!policies_temp)
+ goto fail;
+
+ policies = policies_temp;
+ policies[num_dscp_policies] = policy;
+ num_dscp_policies++;
}
+ wpas_notify_qos_policy_request(wpa_s, policies, num_dscp_policies);
+
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_end");
+
+fail:
+ os_free(policies);
+ return;
}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 9c2d9af0..1d2c3e24 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -681,6 +681,21 @@ struct active_scs_elem {
enum scs_response_status status;
};
+struct dscp_policy_data {
+ u8 policy_id;
+ u8 req_type;
+ u8 dscp;
+ bool dscp_info;
+ const u8 *frame_classifier;
+ u8 frame_classifier_len;
+ struct type4_params type4_param;
+ const u8 *domain_name;
+ u8 domain_name_len;
+ u16 start_port;
+ u16 end_port;
+ bool port_range_info;
+};
+
/**
* struct wpa_supplicant - Internal data for wpa_supplicant interface