• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WPA Supplicant - Helper functions for USD
3  * Copyright (c) 2025, Google Inc. All rights reserved.
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #ifndef MAINLINE_SUPPLICANT_USD_UTILS_H
10 #define MAINLINE_SUPPLICANT_USD_UTILS_H
11 
12 #include "utils.h"
13 
14 #include <aidl/android/system/wifi/mainline_supplicant/IStaInterface.h>
15 #include <aidl/android/system/wifi/mainline_supplicant/UsdServiceProtoType.h>
16 
17 extern "C"
18 {
19 #include "utils/common.h"
20 #include "src/common/nan_de.h"
21 }
22 
23 using ::aidl::android::system::wifi::mainline_supplicant::IStaInterface;
24 using ::aidl::android::system::wifi::mainline_supplicant::UsdServiceProtoType;
25 
26 constexpr bool kIsUsdPublisherSupported = true;
27 constexpr bool kIsUsdSubscriberSupported = true;
28 constexpr int32_t kMaxUsdLocalSsiLengthBytes = 1400;
29 constexpr int32_t kMaxUsdServiceNameLengthBytes = 255;
30 constexpr int32_t kMaxUsdMatchFilterLengthBytes = 0;
31 constexpr int32_t kMaxNumUsdPublishSessions = NAN_DE_MAX_SERVICE;
32 constexpr int32_t kMaxNumUsdSubscribeSessions = NAN_DE_MAX_SERVICE;
33 
validateUsdBaseConfig(IStaInterface::UsdBaseConfig baseConfig)34 static bool validateUsdBaseConfig(IStaInterface::UsdBaseConfig baseConfig) {
35     if (!isValidEnumValue(baseConfig.serviceProtoType,
36             UsdServiceProtoType::GENERIC, UsdServiceProtoType::CSA_MATTER)) {
37         wpa_printf(MSG_ERROR, "Unknown protocol type received: %d",
38             static_cast<int>(baseConfig.serviceProtoType));
39         return false;
40     }
41     if (!checkContainerSize(baseConfig.serviceName, kMaxUsdServiceNameLengthBytes)) {
42         wpa_printf(MSG_ERROR, "Service name of size %zu exceeds the supported size of %d",
43             baseConfig.serviceName.size(), kMaxUsdServiceNameLengthBytes);
44         return false;
45     }
46     if (!checkContainerSize(baseConfig.serviceSpecificInfo, kMaxUsdLocalSsiLengthBytes)) {
47         wpa_printf(MSG_ERROR, "Service specific info of size %zu exceeds"
48             " the supported size of %d", baseConfig.serviceSpecificInfo.size(),
49             kMaxUsdLocalSsiLengthBytes);
50         return false;
51     }
52     if (baseConfig.txMatchFilter.has_value() && !checkContainerSize(
53             baseConfig.txMatchFilter.value(), kMaxUsdMatchFilterLengthBytes)) {
54         wpa_printf(MSG_ERROR, "TX match filter of size %zu exceeds"
55             " the supported size of %d", baseConfig.txMatchFilter.value().size(),
56             kMaxUsdMatchFilterLengthBytes);
57         return false;
58     }
59     if (baseConfig.rxMatchFilter.has_value() && !checkContainerSize(
60             baseConfig.rxMatchFilter.value(), kMaxUsdMatchFilterLengthBytes)) {
61         wpa_printf(MSG_ERROR, "RX match filter of size %zu exceeds"
62             " the supported size of %d", baseConfig.rxMatchFilter.value().size(),
63             kMaxUsdMatchFilterLengthBytes);
64         return false;
65     }
66     return true;
67 }
68 
validateUsdPublishConfig(IStaInterface::UsdPublishConfig publishConfig)69 static bool validateUsdPublishConfig(IStaInterface::UsdPublishConfig publishConfig) {
70     if (!validateUsdBaseConfig(publishConfig.baseConfig)) {
71         return false;
72     }
73     if (!isValidEnumValue(publishConfig.publishType,
74             IStaInterface::UsdPublishType::SOLICITED_ONLY,
75             IStaInterface::UsdPublishType::SOLICITED_AND_UNSOLICITED)) {
76         wpa_printf(MSG_ERROR, "Unknown publish type received: %d",
77             static_cast<int>(publishConfig.publishType));
78         return false;
79     }
80     if (!isValidEnumValue(publishConfig.transmissionType,
81             IStaInterface::UsdPublishTransmissionType::UNICAST,
82             IStaInterface::UsdPublishTransmissionType::MULTICAST)) {
83         wpa_printf(MSG_ERROR, "Unknown transmission type received: %d",
84             static_cast<int>(publishConfig.transmissionType));
85         return false;
86     }
87     return true;
88 }
89 
validateUsdSubscribeConfig(IStaInterface::UsdSubscribeConfig subscribeConfig)90 static bool validateUsdSubscribeConfig(IStaInterface::UsdSubscribeConfig subscribeConfig) {
91     if (!validateUsdBaseConfig(subscribeConfig.baseConfig)) {
92         return false;
93     }
94     if (!isValidEnumValue(subscribeConfig.subscribeType,
95             IStaInterface::UsdSubscribeType::PASSIVE_MODE,
96             IStaInterface::UsdSubscribeType::ACTIVE_MODE)) {
97         wpa_printf(MSG_ERROR, "Unknown subscribe type received: %d",
98             static_cast<int>(subscribeConfig.subscribeType));
99         return false;
100     }
101     return true;
102 }
103 
convertAidlUsdPublishConfigToInternal(IStaInterface::UsdPublishConfig publishConfig)104 static struct nan_publish_params convertAidlUsdPublishConfigToInternal(
105         IStaInterface::UsdPublishConfig publishConfig) {
106     struct nan_publish_params nanPublishParams;
107     nanPublishParams.unsolicited =
108         publishConfig.publishType == IStaInterface::UsdPublishType::SOLICITED_AND_UNSOLICITED
109             || publishConfig.publishType == IStaInterface::UsdPublishType::UNSOLICITED_ONLY;
110     nanPublishParams.solicited =
111         publishConfig.publishType == IStaInterface::UsdPublishType::SOLICITED_AND_UNSOLICITED
112             || publishConfig.publishType == IStaInterface::UsdPublishType::SOLICITED_ONLY;
113     nanPublishParams.solicited_multicast = nanPublishParams.solicited &&
114         publishConfig.transmissionType == IStaInterface::UsdPublishTransmissionType::MULTICAST;
115     nanPublishParams.ttl = publishConfig.baseConfig.ttlSec;
116     nanPublishParams.fsd = publishConfig.isFsd;
117     nanPublishParams.freq = publishConfig.baseConfig.defaultFreqMhz;
118     nanPublishParams.announcement_period = publishConfig.announcementPeriodMillis;
119     nanPublishParams.disable_events = !publishConfig.eventsEnabled;
120     // Pass the original pointer to the freq list, since the receiver will memcpy the data
121     nanPublishParams.freq_list = publishConfig.baseConfig.freqsMhz.empty()
122         ? NULL : publishConfig.baseConfig.freqsMhz.data();
123     return nanPublishParams;
124 }
125 
convertAidlUsdSubscribeConfigToInternal(IStaInterface::UsdSubscribeConfig subscribeConfig)126 static struct nan_subscribe_params convertAidlUsdSubscribeConfigToInternal(
127         IStaInterface::UsdSubscribeConfig subscribeConfig) {
128     struct nan_subscribe_params nanSubscribeParams;
129     nanSubscribeParams.active =
130         subscribeConfig.subscribeType == IStaInterface::UsdSubscribeType::ACTIVE_MODE;
131     nanSubscribeParams.ttl = subscribeConfig.baseConfig.ttlSec;
132     nanSubscribeParams.freq = subscribeConfig.baseConfig.defaultFreqMhz;
133     nanSubscribeParams.query_period = subscribeConfig.queryPeriodMillis;
134     // Pass the original pointer to the freq list, since the receiver will memcpy the data
135     nanSubscribeParams.freq_list = subscribeConfig.baseConfig.freqsMhz.empty()
136         ? NULL : subscribeConfig.baseConfig.freqsMhz.data();
137     return nanSubscribeParams;
138 }
139 
convertAidlServiceProtoTypeToInternal(UsdServiceProtoType serviceProtoType)140 static nan_service_protocol_type convertAidlServiceProtoTypeToInternal(
141         UsdServiceProtoType serviceProtoType) {
142     switch (serviceProtoType) {
143         case UsdServiceProtoType::GENERIC:
144             return NAN_SRV_PROTO_GENERIC;
145         case UsdServiceProtoType::CSA_MATTER:
146             return NAN_SRV_PROTO_CSA_MATTER;
147         default:
148             // Default case is not expected, due to the USD validation method
149             return NAN_SRV_PROTO_GENERIC;
150     };
151 }
152 
convertInternalUsdServiceProtoTypeToAidl(nan_service_protocol_type protocolType)153 static UsdServiceProtoType convertInternalUsdServiceProtoTypeToAidl(
154         nan_service_protocol_type protocolType) {
155     switch (protocolType) {
156         case NAN_SRV_PROTO_GENERIC:
157             return UsdServiceProtoType::GENERIC;
158         case NAN_SRV_PROTO_CSA_MATTER:
159             return UsdServiceProtoType::CSA_MATTER;
160         default:
161             wpa_printf(MSG_ERROR, "Received invalid USD proto type %d from internal",
162                 static_cast<int>(protocolType));
163             return UsdServiceProtoType::GENERIC;
164     }
165 }
166 
createUsdServiceDiscoveryInfo(enum nan_service_protocol_type srv_proto_type,int own_id,int peer_id,const u8 * peer_addr,bool fsd,const u8 * ssi,size_t ssi_len)167 static IStaInterfaceCallback::UsdServiceDiscoveryInfo createUsdServiceDiscoveryInfo(
168         enum nan_service_protocol_type srv_proto_type,
169         int own_id, int peer_id, const u8 *peer_addr,
170         bool fsd, const u8 *ssi, size_t ssi_len) {
171     IStaInterfaceCallback::UsdServiceDiscoveryInfo discoveryInfo;
172     discoveryInfo.ownId = own_id;
173     discoveryInfo.peerId = peer_id;
174     // TODO: Fill the matchFilter field in the AIDL struct
175     discoveryInfo.matchFilter = std::vector<uint8_t>();
176     discoveryInfo.peerMacAddress = macAddrBytesToArray(peer_addr);
177     discoveryInfo.serviceProtoType = convertInternalUsdServiceProtoTypeToAidl(srv_proto_type);
178     discoveryInfo.serviceSpecificInfo = ssi ? byteArrToVec(ssi, ssi_len) : std::vector<uint8_t>();
179     discoveryInfo.isFsd = fsd;
180     return discoveryInfo;
181 }
182 
convertInternalUsdTerminateReasonCodeToAidl(nan_de_reason terminateReason)183 static IStaInterfaceCallback::UsdTerminateReasonCode convertInternalUsdTerminateReasonCodeToAidl(
184         nan_de_reason terminateReason) {
185     switch (terminateReason) {
186         case NAN_DE_REASON_TIMEOUT:
187             return IStaInterfaceCallback::UsdTerminateReasonCode::TIMEOUT;
188         case NAN_DE_REASON_USER_REQUEST:
189             return IStaInterfaceCallback::UsdTerminateReasonCode::USER_REQUESTED;
190         case NAN_DE_REASON_FAILURE:
191         default:
192             return IStaInterfaceCallback::UsdTerminateReasonCode::FAILURE_UNKNOWN;
193     }
194 }
195 
196 #endif // MAINLINE_SUPPLICANT_USD_UTILS_H
197