• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.aware;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 
22 import java.util.Arrays;
23 
24 /**
25  * Defines a request object to configure a Wi-Fi Aware network. Built using
26  * {@link ConfigRequest.Builder}. Configuration is requested using
27  * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}.
28  * Note that the actual achieved configuration may be different from the
29  * requested configuration - since different applications may request different
30  * configurations.
31  *
32  * @hide
33  */
34 public final class ConfigRequest implements Parcelable {
35     /**
36      * Lower range of possible cluster ID.
37      */
38     public static final int CLUSTER_ID_MIN = 0;
39 
40     /**
41      * Upper range of possible cluster ID.
42      */
43     public static final int CLUSTER_ID_MAX = 0xFFFF;
44 
45     /**
46      * Indices for configuration variables which are specified per band.
47      */
48     public static final int NAN_BAND_24GHZ = 0;
49     public static final int NAN_BAND_5GHZ = 1;
50     public static final int NAN_BAND_6GHZ = 2;
51 
52     /**
53      * Magic values for Discovery Window (DW) interval configuration
54      */
55     public static final int DW_INTERVAL_NOT_INIT = -1;
56     public static final int DW_DISABLE = 0; // only valid for 5GHz
57 
58     /**
59      * Indicates whether 5G band support is requested.
60      */
61     public final boolean mSupport5gBand;
62 
63     /**
64      * Indicates whether 6G band support is requested.
65      */
66     public final boolean mSupport6gBand;
67 
68     /**
69      * Specifies the desired master preference.
70      */
71     public final int mMasterPreference;
72 
73     /**
74      * Specifies the desired lower range of the cluster ID. Must be lower then
75      * {@link ConfigRequest#mClusterHigh}.
76      */
77     public final int mClusterLow;
78 
79     /**
80      * Specifies the desired higher range of the cluster ID. Must be higher then
81      * {@link ConfigRequest#mClusterLow}.
82      */
83     public final int mClusterHigh;
84 
85     /**
86      * Specifies the discovery window interval for the device on NAN_BAND_*.
87      */
88     public final int mDiscoveryWindowInterval[];
89 
ConfigRequest(boolean support5gBand, boolean support6gBand, int masterPreference, int clusterLow, int clusterHigh, int[] discoveryWindowInterval)90     private ConfigRequest(boolean support5gBand, boolean support6gBand, int masterPreference,
91             int clusterLow, int clusterHigh, int[] discoveryWindowInterval) {
92         mSupport5gBand = support5gBand;
93         mSupport6gBand = support6gBand;
94         mMasterPreference = masterPreference;
95         mClusterLow = clusterLow;
96         mClusterHigh = clusterHigh;
97         mDiscoveryWindowInterval = discoveryWindowInterval;
98     }
99 
100     @Override
toString()101     public String toString() {
102         return "ConfigRequest [mSupport5gBand=" + mSupport5gBand
103                 + ", mSupport6gBand=" + mSupport6gBand
104                 + ", mMasterPreference=" + mMasterPreference
105                 + ", mClusterLow=" + mClusterLow
106                 + ", mClusterHigh=" + mClusterHigh
107                 + ", mDiscoveryWindowInterval=" + Arrays.toString(mDiscoveryWindowInterval) + "]";
108     }
109 
110     @Override
describeContents()111     public int describeContents() {
112         return 0;
113     }
114 
115     @Override
writeToParcel(Parcel dest, int flags)116     public void writeToParcel(Parcel dest, int flags) {
117         dest.writeInt(mSupport5gBand ? 1 : 0);
118         dest.writeInt(mSupport6gBand ? 1 : 0);
119         dest.writeInt(mMasterPreference);
120         dest.writeInt(mClusterLow);
121         dest.writeInt(mClusterHigh);
122         dest.writeIntArray(mDiscoveryWindowInterval);
123     }
124 
125     public static final @android.annotation.NonNull Creator<ConfigRequest> CREATOR = new Creator<ConfigRequest>() {
126         @Override
127         public ConfigRequest[] newArray(int size) {
128             return new ConfigRequest[size];
129         }
130 
131         @Override
132         public ConfigRequest createFromParcel(Parcel in) {
133             boolean support5gBand = in.readInt() != 0;
134             boolean support6gBand = in.readInt() != 0;
135             int masterPreference = in.readInt();
136             int clusterLow = in.readInt();
137             int clusterHigh = in.readInt();
138             int discoveryWindowInterval[] = in.createIntArray();
139 
140             return new ConfigRequest(support5gBand, support6gBand, masterPreference, clusterLow,
141                     clusterHigh, discoveryWindowInterval);
142         }
143     };
144 
145     @Override
equals(Object o)146     public boolean equals(Object o) {
147         if (this == o) {
148             return true;
149         }
150 
151         if (!(o instanceof ConfigRequest)) {
152             return false;
153         }
154 
155         ConfigRequest lhs = (ConfigRequest) o;
156 
157         return mSupport5gBand == lhs.mSupport5gBand
158                 && mSupport6gBand == lhs.mSupport6gBand
159                 && mMasterPreference == lhs.mMasterPreference
160                 && mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh
161                 && Arrays.equals(mDiscoveryWindowInterval, lhs.mDiscoveryWindowInterval);
162     }
163 
164     @Override
hashCode()165     public int hashCode() {
166         int result = 17;
167 
168         result = 31 * result + (mSupport5gBand ? 1 : 0);
169         result = 31 * result + (mSupport6gBand ? 1 : 0);
170         result = 31 * result + mMasterPreference;
171         result = 31 * result + mClusterLow;
172         result = 31 * result + mClusterHigh;
173         result = 31 * result + Arrays.hashCode(mDiscoveryWindowInterval);
174 
175         return result;
176     }
177 
178     /**
179      * Verifies that the contents of the ConfigRequest are valid. Otherwise
180      * throws an IllegalArgumentException.
181      */
validate()182     public void validate() throws IllegalArgumentException {
183         if (mMasterPreference < 0) {
184             throw new IllegalArgumentException(
185                     "Master Preference specification must be non-negative");
186         }
187         if (mMasterPreference == 1 || mMasterPreference == 255 || mMasterPreference > 255) {
188             throw new IllegalArgumentException("Master Preference specification must not "
189                     + "exceed 255 or use 1 or 255 (reserved values)");
190         }
191         if (mClusterLow < CLUSTER_ID_MIN) {
192             throw new IllegalArgumentException("Cluster specification must be non-negative");
193         }
194         if (mClusterLow > CLUSTER_ID_MAX) {
195             throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
196         }
197         if (mClusterHigh < CLUSTER_ID_MIN) {
198             throw new IllegalArgumentException("Cluster specification must be non-negative");
199         }
200         if (mClusterHigh > CLUSTER_ID_MAX) {
201             throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
202         }
203         if (mClusterLow > mClusterHigh) {
204             throw new IllegalArgumentException(
205                     "Invalid argument combination - must have Cluster Low <= Cluster High");
206         }
207         if (mDiscoveryWindowInterval.length != 3) {
208             throw new IllegalArgumentException(
209                     "Invalid discovery window interval: must have 3 elements (2.4 & 5 & 6");
210         }
211         if (mDiscoveryWindowInterval[NAN_BAND_24GHZ] != DW_INTERVAL_NOT_INIT &&
212                 (mDiscoveryWindowInterval[NAN_BAND_24GHZ] < 1 // valid for 2.4GHz: [1-5]
213                 || mDiscoveryWindowInterval[NAN_BAND_24GHZ] > 5)) {
214             throw new IllegalArgumentException(
215                     "Invalid discovery window interval for 2.4GHz: valid is UNSET or [1,5]");
216         }
217         if (mDiscoveryWindowInterval[NAN_BAND_5GHZ] != DW_INTERVAL_NOT_INIT &&
218                 (mDiscoveryWindowInterval[NAN_BAND_5GHZ] < 0 // valid for 5GHz: [0-5]
219                 || mDiscoveryWindowInterval[NAN_BAND_5GHZ] > 5)) {
220             throw new IllegalArgumentException(
221                 "Invalid discovery window interval for 5GHz: valid is UNSET or [0,5]");
222         }
223         if (mDiscoveryWindowInterval[NAN_BAND_6GHZ] != DW_INTERVAL_NOT_INIT
224                 && (mDiscoveryWindowInterval[NAN_BAND_6GHZ] < 0 // valid for 6GHz: [0-5]
225                 || mDiscoveryWindowInterval[NAN_BAND_6GHZ] > 5)) {
226             throw new IllegalArgumentException(
227                 "Invalid discovery window interval for 6GHz: valid is UNSET or [0,5]");
228         }
229     }
230 
231     /**
232      * Builder used to build {@link ConfigRequest} objects.
233      */
234     public static final class Builder {
235         private boolean mSupport5gBand = true;
236         private boolean mSupport6gBand = false;
237         private int mMasterPreference = 0;
238         private int mClusterLow = CLUSTER_ID_MIN;
239         private int mClusterHigh = CLUSTER_ID_MAX;
240         private int[] mDiscoveryWindowInterval = {DW_INTERVAL_NOT_INIT, DW_INTERVAL_NOT_INIT,
241                 DW_INTERVAL_NOT_INIT};
242 
243         /**
244          * Specify whether 5G band support is required in this request. Disabled by default.
245          *
246          * @param support5gBand Support for 5G band is required.
247          *
248          * @return The builder to facilitate chaining
249          *         {@code builder.setXXX(..).setXXX(..)}.
250          */
setSupport5gBand(boolean support5gBand)251         public Builder setSupport5gBand(boolean support5gBand) {
252             mSupport5gBand = support5gBand;
253             return this;
254         }
255 
256         /**
257          * Specify whether 6G band support is required in this request. Disabled by default.
258          *
259          * @param support6gBand Support for 6G band is required.
260          *
261          * @return The builder to facilitate chaining
262          *         {@code builder.setXXX(..).setXXX(..)}.
263          */
setSupport6gBand(boolean support6gBand)264         public Builder setSupport6gBand(boolean support6gBand) {
265             mSupport6gBand = support6gBand;
266             return this;
267         }
268 
269         /**
270          * Specify the Master Preference requested. The permitted range is 0 (the default) to
271          * 255 with 1 and 255 excluded (reserved).
272          *
273          * @param masterPreference The requested master preference
274          *
275          * @return The builder to facilitate chaining
276          *         {@code builder.setXXX(..).setXXX(..)}.
277          */
setMasterPreference(int masterPreference)278         public Builder setMasterPreference(int masterPreference) {
279             if (masterPreference < 0) {
280                 throw new IllegalArgumentException(
281                         "Master Preference specification must be non-negative");
282             }
283             if (masterPreference == 1 || masterPreference == 255 || masterPreference > 255) {
284                 throw new IllegalArgumentException("Master Preference specification must not "
285                         + "exceed 255 or use 1 or 255 (reserved values)");
286             }
287 
288             mMasterPreference = masterPreference;
289             return this;
290         }
291 
292         /**
293          * The Cluster ID is generated randomly for new Aware networks. Specify
294          * the lower range of the cluster ID. The upper range is specified using
295          * the {@link ConfigRequest.Builder#setClusterHigh(int)}. The permitted
296          * range is 0 (the default) to the value specified by
297          * {@link ConfigRequest.Builder#setClusterHigh(int)}. Equality of Low and High is
298          * permitted which restricts the Cluster ID to the specified value.
299          *
300          * @param clusterLow The lower range of the generated cluster ID.
301          *
302          * @return The builder to facilitate chaining
303          *         {@code builder.setClusterLow(..).setClusterHigh(..)}.
304          */
setClusterLow(int clusterLow)305         public Builder setClusterLow(int clusterLow) {
306             if (clusterLow < CLUSTER_ID_MIN) {
307                 throw new IllegalArgumentException("Cluster specification must be non-negative");
308             }
309             if (clusterLow > CLUSTER_ID_MAX) {
310                 throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
311             }
312 
313             mClusterLow = clusterLow;
314             return this;
315         }
316 
317         /**
318          * The Cluster ID is generated randomly for new Aware networks. Specify
319          * the lower upper of the cluster ID. The lower range is specified using
320          * the {@link ConfigRequest.Builder#setClusterLow(int)}. The permitted
321          * range is the value specified by
322          * {@link ConfigRequest.Builder#setClusterLow(int)} to 0xFFFF (the default). Equality of
323          * Low and High is permitted which restricts the Cluster ID to the specified value.
324          *
325          * @param clusterHigh The upper range of the generated cluster ID.
326          *
327          * @return The builder to facilitate chaining
328          *         {@code builder.setClusterLow(..).setClusterHigh(..)}.
329          */
setClusterHigh(int clusterHigh)330         public Builder setClusterHigh(int clusterHigh) {
331             if (clusterHigh < CLUSTER_ID_MIN) {
332                 throw new IllegalArgumentException("Cluster specification must be non-negative");
333             }
334             if (clusterHigh > CLUSTER_ID_MAX) {
335                 throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
336             }
337 
338             mClusterHigh = clusterHigh;
339             return this;
340         }
341 
342         /**
343          * The discovery window interval specifies the discovery windows in which the device will be
344          * awake. The configuration enables trading off latency vs. power (higher interval means
345          * higher discovery latency but lower power).
346          *
347          * @param band Either {@link #NAN_BAND_24GHZ} or {@link #NAN_BAND_5GHZ} or
348          *        {@link #NAN_BAND_6GHZ}.
349          * @param interval A value of 1, 2, 3, 4, or 5 indicating an interval of 2^(interval-1). For
350          *                 the 5GHz band a value of 0 indicates that the device will not be awake
351          *                 for any discovery windows.
352          *
353          * @return The builder itself to facilitate chaining operations
354          *         {@code builder.setDiscoveryWindowInterval(...).setMasterPreference(...)}.
355          */
setDiscoveryWindowInterval(int band, int interval)356         public Builder setDiscoveryWindowInterval(int band, int interval) {
357             if (band != NAN_BAND_24GHZ && band != NAN_BAND_5GHZ && band != NAN_BAND_6GHZ) {
358                 throw new IllegalArgumentException("Invalid band value");
359             }
360             if ((band == NAN_BAND_24GHZ && (interval < 1 || interval > 5))
361                     || (band == NAN_BAND_5GHZ && (interval < 0 || interval > 5))
362                     || (band == NAN_BAND_6GHZ && (interval < 0 || interval > 5))) {
363                 throw new IllegalArgumentException(
364                         "Invalid interval value: 2.4 GHz [1,5] or 5GHz/6GHz [0,5]");
365             }
366 
367             mDiscoveryWindowInterval[band] = interval;
368             return this;
369         }
370 
371         /**
372          * Build {@link ConfigRequest} given the current requests made on the
373          * builder.
374          */
build()375         public ConfigRequest build() {
376             if (mClusterLow > mClusterHigh) {
377                 throw new IllegalArgumentException(
378                         "Invalid argument combination - must have Cluster Low <= Cluster High");
379             }
380 
381             return new ConfigRequest(mSupport5gBand, mSupport6gBand, mMasterPreference, mClusterLow,
382                     mClusterHigh, mDiscoveryWindowInterval);
383         }
384     }
385 }
386