• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net.wifi.usd;
18 
19 import android.annotation.FlaggedApi;
20 import android.annotation.IntDef;
21 import android.annotation.IntRange;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.SystemApi;
25 import android.net.wifi.aware.TlvBufferUtils;
26 import android.net.wifi.flags.Flags;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 import java.util.Arrays;
31 import java.util.List;
32 import java.util.Objects;
33 
34 /**
35  * USD configuration for publish and subscribe operation. This is the base class and not intended
36  * to be created directly.
37  *
38  * @hide
39  */
40 @SystemApi
41 @FlaggedApi(Flags.FLAG_USD)
42 public abstract class Config {
43     /** @hide */
44     public static final int MAX_NUM_OF_OPERATING_FREQUENCIES = 32;
45 
46     /**
47      * Transmission type.
48      *
49      * @hide
50      */
51     @IntDef({TRANSMISSION_TYPE_UNICAST, TRANSMISSION_TYPE_MULTICAST})
52     @Retention(RetentionPolicy.SOURCE)
53     public @interface TransmissionType {
54     }
55 
56     /**
57      * A unicast transmission sends data from one device to a single, specific destination device.
58      */
59     public static final int TRANSMISSION_TYPE_UNICAST = 0;
60 
61     /**
62      * A multicast transmission sends data from one device to a group of devices on the network
63      * simultaneously.
64      */
65     public static final int TRANSMISSION_TYPE_MULTICAST = 1;
66 
67     /**
68      * Subscribe type.
69      *
70      * @hide
71      */
72     @IntDef({SUBSCRIBE_TYPE_PASSIVE, SUBSCRIBE_TYPE_ACTIVE})
73     @Retention(RetentionPolicy.SOURCE)
74     public @interface SubscribeType {
75     }
76 
77     /**
78      * Defines a passive subscribe session - a subscribe session where subscribe packets are not
79      * transmitted over-the-air and the device listens and matches to received publish packets.
80      */
81     public static final int SUBSCRIBE_TYPE_PASSIVE = 0;
82 
83     /**
84      * Defines an active subscribe session - a subscribe session where subscribe packets are
85      * transmitted over-the-air.
86      */
87     public static final int SUBSCRIBE_TYPE_ACTIVE = 1;
88 
89     /**
90      * Service Protocol Type.
91      *
92      * @hide
93      */
94     @IntDef({SERVICE_PROTO_TYPE_GENERIC, SERVICE_PROTO_TYPE_CSA_MATTER})
95     @Retention(RetentionPolicy.SOURCE)
96     public @interface ServiceProtoType {
97     }
98 
99     /**
100      * Generic type.
101      */
102     public static final int SERVICE_PROTO_TYPE_GENERIC = 0;
103 
104     /**
105      * CSA (Connectivity Standards Alliance) Matter.
106      * Note: CSA Matter is an open-source standard for smart home technology that allows devices to
107      * work with any Matter-certified ecosystem.
108      */
109     public static final int SERVICE_PROTO_TYPE_CSA_MATTER = 1;
110 
111     private final byte[] mServiceName;
112     private final int mTtlSeconds;
113     @ServiceProtoType
114     private final int mServiceProtoType;
115     private final byte[] mTxMatchFilterTlv;
116     private final byte[] mRxMatchFilterTlv;
117     private final byte[] mServiceSpecificInfo;
118     private final int[] mOperatingFrequencies;
119 
120     /**
121      * @hide
122      */
Config(@onNull byte[] serviceName, int ttlSeconds, int serviceProtoType, @Nullable byte[] txMatchFilterTlv, @Nullable byte[] rxMatchFilterTlv, @Nullable byte[] serviceSpecificInfo, @Nullable int[] operatingFrequencies)123     public Config(@NonNull byte[] serviceName, int ttlSeconds, int serviceProtoType,
124             @Nullable byte[] txMatchFilterTlv, @Nullable byte[] rxMatchFilterTlv,
125             @Nullable byte[] serviceSpecificInfo, @Nullable int[] operatingFrequencies) {
126         mServiceName = serviceName;
127         mTtlSeconds = ttlSeconds;
128         mServiceProtoType = serviceProtoType;
129         mTxMatchFilterTlv = txMatchFilterTlv;
130         mRxMatchFilterTlv = rxMatchFilterTlv;
131         mServiceSpecificInfo = serviceSpecificInfo;
132         mOperatingFrequencies = operatingFrequencies;
133     }
134 
135     /**
136      * Gets the service name of the USD session.
137      * <p>
138      * The Service Name is a UTF-8 encoded string from 1 to 255 bytes in length.
139      * The only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric
140      * values (A-Z, a-z, 0-9), the hyphen ('-'), the period ('.') and the underscore ('_'). All
141      * valid multi-byte UTF-8 characters are acceptable in a Service Name.
142      *
143      * @return service name
144      */
145     @NonNull
getServiceName()146     public byte[] getServiceName() {
147         return mServiceName;
148     }
149 
150     /**
151      * Gets the time interval (in seconds) a USD session will be alive. When the TTL is reached the
152      * session will be terminated with an event.
153      *
154      * @return ttl value in seconds
155      */
156     @IntRange(from = 0)
getTtlSeconds()157     public int getTtlSeconds() {
158         return mTtlSeconds;
159     }
160 
161     /**
162      * Get the Service protocol type for the USD session.
163      *
164      * @return service protocol type as defined in {@code SERVICE_PROTOCOL_TYPE_*}
165      */
166     @ServiceProtoType
getServiceProtoType()167     public int getServiceProtoType() {
168         return mServiceProtoType;
169     }
170 
171     /**
172      * Gets the Tx filter which is an ordered sequence of (length, value) pairs to be included in
173      * the USD discovery frame.
174      *
175      * @return tx match filter or empty list
176      */
177     @NonNull
getTxMatchFilter()178     public List<byte[]> getTxMatchFilter() {
179         return new TlvBufferUtils.TlvIterable(0, 1, mTxMatchFilterTlv).toList();
180     }
181 
182     /**
183      * @return tx match filter in TLV format
184      * @hide
185      */
186     @Nullable
getTxMatchFilterTlv()187     public byte[] getTxMatchFilterTlv() {
188         return mTxMatchFilterTlv;
189     }
190 
191     /**
192      * Gets the Rx match filter, which is an ordered sequence of (length, value) pairs that specify
193      * further the response conditions beyond the service name used to filter subscribe messages.
194      *
195      * @return rx match filter or empty list
196      */
197     @NonNull
getRxMatchFilter()198     public List<byte[]> getRxMatchFilter() {
199         return new TlvBufferUtils.TlvIterable(0, 1, mRxMatchFilterTlv).toList();
200     }
201 
202     /**
203      * @return receive match filter in TLV format.
204      * @hide
205      */
206     @Nullable
getRxMatchFilterTlv()207     public byte[] getRxMatchFilterTlv() {
208         return mRxMatchFilterTlv;
209     }
210 
211     /**
212      * Get the service specific information set for the USD session.
213      *
214      * @return byte array or null
215      */
216     @Nullable
getServiceSpecificInfo()217     public byte[] getServiceSpecificInfo() {
218         return mServiceSpecificInfo;
219     }
220 
221     /**
222      * Get the frequencies where the USD session operates if overridden by {@code
223      * setOperatingFrequenciesMhz(int[])}. If null, the application has not set the operating
224      * frequencies using {@link PublishConfig.Builder#setOperatingFrequenciesMhz(int[])} for the
225      * publisher or {@link SubscribeConfig.Builder#setOperatingFrequenciesMhz(int[])} for the
226      * subscriber.
227      *
228      * <p>If the operating frequencies are not set the default behavior for the publisher and
229      * subscriber is,
230      * <ul>
231      * <li>The publisher defaults to channel 6 (in the 2.4 GHz band) and a list of allowed channels
232      * in the 2.4 GHz and 5 GHz bands for multichannel publishing. Publisher may prioritize the
233      * channel with Access Points having best RSSI.
234      * <li>The subscriber defaults to either channel 6 (in the 2.4 Ghz band) or Station channel or
235      * pick a channel from
236      * {@link SubscribeConfig.Builder#setRecommendedOperatingFrequenciesMhz(int[])} in given order
237      * of preference.
238      * </ul>
239      *
240      * @return an array of frequencies or null
241      */
242     @Nullable
getOperatingFrequenciesMhz()243     public int[] getOperatingFrequenciesMhz() {
244         return mOperatingFrequencies;
245     }
246 
247     @Override
toString()248     public String toString() {
249         return "Config{" + "mServiceName=" + Arrays.toString(mServiceName) + ", mTtlSeconds="
250                 + mTtlSeconds + ", mServiceProtoType=" + mServiceProtoType + ", mTxMatchFilterTlv="
251                 + Arrays.toString(mTxMatchFilterTlv) + ", mRxMatchFilterTlv=" + Arrays.toString(
252                 mRxMatchFilterTlv) + ", mServiceSpecificInfo=" + Arrays.toString(
253                 mServiceSpecificInfo) + ", mOperatingFrequencies=" + Arrays.toString(
254                 mOperatingFrequencies) + '}';
255     }
256 
257     @Override
equals(Object o)258     public boolean equals(Object o) {
259         if (this == o) return true;
260         if (!(o instanceof Config config)) return false;
261         return mTtlSeconds == config.mTtlSeconds && mServiceProtoType == config.mServiceProtoType
262                 && Arrays.equals(mServiceName, config.mServiceName)
263                 && Arrays.equals(mTxMatchFilterTlv, config.mTxMatchFilterTlv)
264                 && Arrays.equals(mRxMatchFilterTlv, config.mRxMatchFilterTlv)
265                 && Arrays.equals(mServiceSpecificInfo, config.mServiceSpecificInfo)
266                 && Arrays.equals(mOperatingFrequencies, config.mOperatingFrequencies);
267     }
268 
269     @Override
hashCode()270     public int hashCode() {
271         int result = Objects.hash(mTtlSeconds, mServiceProtoType);
272         result = 31 * result + Arrays.hashCode(mServiceName);
273         result = 31 * result + Arrays.hashCode(mTxMatchFilterTlv);
274         result = 31 * result + Arrays.hashCode(mRxMatchFilterTlv);
275         result = 31 * result + Arrays.hashCode(mServiceSpecificInfo);
276         result = 31 * result + Arrays.hashCode(mOperatingFrequencies);
277         return result;
278     }
279 }
280