diff options
author | Gabriel Biren <gbiren@google.com> | 2022-05-05 19:36:43 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-05-05 19:36:43 +0000 |
commit | 5f523c76c4cc69e62e3c4d3713a00116aecc28fb (patch) | |
tree | 94112c418fdd2a3742abc0fe756060c66db8a163 | |
parent | cfc3487ddb3839cec413a016721570725805a987 (diff) | |
parent | 9d7720d3ef7dba6e4d41ddba4f20af947fbbd5be (diff) | |
download | wpa_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.cpp | 32 | ||||
-rw-r--r-- | wpa_supplicant/aidl/aidl.h | 8 | ||||
-rw-r--r-- | wpa_supplicant/aidl/aidl_manager.cpp | 131 | ||||
-rw-r--r-- | wpa_supplicant/aidl/aidl_manager.h | 4 | ||||
-rw-r--r-- | wpa_supplicant/aidl/sta_iface.cpp | 42 | ||||
-rw-r--r-- | wpa_supplicant/notify.c | 17 | ||||
-rw-r--r-- | wpa_supplicant/notify.h | 3 | ||||
-rw-r--r-- | wpa_supplicant/robust_av.c | 54 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant_i.h | 15 |
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 |