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.annotation.IntDef;
20 import android.annotation.IntRange;
21 import android.os.Build;
22 import android.os.Bundle;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import androidx.annotation.RequiresApi;
27 
28 import com.android.modules.utils.build.SdkLevel;
29 
30 import java.lang.annotation.Retention;
31 import java.lang.annotation.RetentionPolicy;
32 
33 /**
34  * The characteristics of the Wi-Fi Aware implementation.
35  */
36 public final class Characteristics implements Parcelable {
37     /** @hide */
38     public static final String KEY_MAX_SERVICE_NAME_LENGTH = "key_max_service_name_length";
39     /** @hide */
40     public static final String KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH =
41             "key_max_service_specific_info_length";
42     /** @hide */
43     public static final String KEY_MAX_MATCH_FILTER_LENGTH = "key_max_match_filter_length";
44     /** @hide */
45     public static final String KEY_SUPPORTED_DATA_PATH_CIPHER_SUITES =
46             "key_supported_data_path_cipher_suites";
47     /** @hide */
48     public static final String KEY_SUPPORTED_PAIRING_CIPHER_SUITES =
49             "key_supported_pairing_cipher_suites";
50     /** @hide */
51     public static final String KEY_IS_INSTANT_COMMUNICATION_MODE_SUPPORTED =
52             "key_is_instant_communication_mode_supported";
53     /** @hide */
54     public static final String KEY_MAX_NDP_NUMBER = "key_max_ndp_number";
55     /** @hide */
56     public static final String KEY_MAX_PUBLISH_NUMBER = "key_max_publish_number";
57     /** @hide */
58     public static final String KEY_MAX_SUBSCRIBE_NUMBER = "key_max_subscribe_number";
59     /** @hide */
60     public static final String KEY_MAX_NDI_NUMBER = "key_max_ndi_number";
61     /** @hide */
62     public static final String KEY_SUPPORT_NAN_PAIRING = "key_support_nan_pairing";
63     /** @hide */
64     public static final String KEY_SUPPORT_SUSPENSION = "key_support_suspension";
65 
66     private final Bundle mCharacteristics;
67 
68     /** @hide : should not be created by apps */
Characteristics(Bundle characteristics)69     public Characteristics(Bundle characteristics) {
70         mCharacteristics = characteristics;
71     }
72 
73     /**
74      * Returns the maximum string length that can be used to specify a Aware service name. Restricts
75      * the parameters of the {@link PublishConfig.Builder#setServiceName(String)} and
76      * {@link SubscribeConfig.Builder#setServiceName(String)}.
77      *
78      * @return A positive integer, maximum string length of Aware service name.
79      */
getMaxServiceNameLength()80     public int getMaxServiceNameLength() {
81         return mCharacteristics.getInt(KEY_MAX_SERVICE_NAME_LENGTH);
82     }
83 
84     /**
85      * Returns the maximum length of byte array that can be used to specify a Aware service specific
86      * information field: the arbitrary load used in discovery or the message length of Aware
87      * message exchange. Restricts the parameters of the
88      * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])},
89      * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and
90      * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}
91      * variants.
92      *
93      * @return A positive integer, maximum length of byte array for Aware messaging.
94      */
getMaxServiceSpecificInfoLength()95     public int getMaxServiceSpecificInfoLength() {
96         return mCharacteristics.getInt(KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH);
97     }
98 
99     /**
100      * Returns the maximum length of byte array that can be used to specify a Aware match filter.
101      * Restricts the parameters of the
102      * {@link PublishConfig.Builder#setMatchFilter(java.util.List)} and
103      * {@link SubscribeConfig.Builder#setMatchFilter(java.util.List)}.
104      *
105      * @return A positive integer, maximum length of byte array for Aware discovery match filter.
106      */
getMaxMatchFilterLength()107     public int getMaxMatchFilterLength() {
108         return mCharacteristics.getInt(KEY_MAX_MATCH_FILTER_LENGTH);
109     }
110 
111     /**
112      * Returns the maximum number of Aware data interfaces supported by the device.
113      *
114      * @return A positive integer, maximum number of Aware data interfaces supported by the device.
115      */
116     @IntRange(from = 1)
getNumberOfSupportedDataInterfaces()117     public int getNumberOfSupportedDataInterfaces() {
118         return mCharacteristics.getInt(KEY_MAX_NDI_NUMBER);
119     }
120 
121     /**
122      * Returns the maximum number of Aware publish sessions supported by the device.
123      * Use {@link AwareResources#getAvailablePublishSessionsCount()} to get the number of available
124      * publish sessions which are not currently used by any app.
125      *
126      * @return A positive integer, maximum number of publish sessions supported by the device.
127      */
128     @IntRange(from = 1)
getNumberOfSupportedPublishSessions()129     public int getNumberOfSupportedPublishSessions() {
130         return mCharacteristics.getInt(KEY_MAX_PUBLISH_NUMBER);
131     }
132 
133     /**
134      * Returns the maximum number of Aware subscribe session supported by the device.
135      * Use {@link AwareResources#getAvailableSubscribeSessionsCount()} to get the number of
136      * available subscribe sessions which are not currently used by any app.
137      *
138      * @return A positive integer, maximum number of subscribe sessions supported by the device.
139      */
140     @IntRange(from = 1)
getNumberOfSupportedSubscribeSessions()141     public int getNumberOfSupportedSubscribeSessions() {
142         return mCharacteristics.getInt(KEY_MAX_SUBSCRIBE_NUMBER);
143     }
144 
145     /**
146      * Returns the maximum number of Aware data paths(also known as NDPs - NAN Data Paths) supported
147      * by the device.
148      * Use {@link AwareResources#getAvailableDataPathsCount()} to get the number of available Aware
149      * data paths which are not currently used by any app.
150      *
151      * @return A positive integer, maximum number of Aware data paths supported by the device.
152      */
153     @IntRange(from = 1)
getNumberOfSupportedDataPaths()154     public int getNumberOfSupportedDataPaths() {
155         return mCharacteristics.getInt(KEY_MAX_NDP_NUMBER);
156     }
157 
158     /**
159      * Check if instant communication mode is supported by device. The instant communication mode is
160      * defined as per Wi-Fi Alliance (WFA) Wi-Fi Aware specifications version 3.1 Section 12.3.
161      * @return True if supported, false otherwise.
162      */
163     @RequiresApi(Build.VERSION_CODES.S)
isInstantCommunicationModeSupported()164     public boolean isInstantCommunicationModeSupported() {
165         if (!SdkLevel.isAtLeastS()) {
166             throw new UnsupportedOperationException();
167         }
168         return mCharacteristics.getBoolean(KEY_IS_INSTANT_COMMUNICATION_MODE_SUPPORTED);
169     }
170 
171     /**
172      * Check if the Aware Pairing is supported. The Aware Pairing is defined as per Wi-Fi Alliance
173      * (WFA) Wi-Fi Aware specifications version 4.0 Section 7.6.
174      * @return True if supported, false otherwise.
175      */
isAwarePairingSupported()176     public boolean isAwarePairingSupported() {
177         return mCharacteristics.getBoolean(KEY_SUPPORT_NAN_PAIRING);
178     }
179 
180     /**
181      * Check if Aware Suspension is supported. Aware Suspension is a mechanism of putting an Aware
182      * connection in and out of a low-power mode while preserving the discovery sessions and data
183      * paths.
184      * @return True if supported, false otherwise.
185      */
isSuspensionSupported()186     public boolean isSuspensionSupported() {
187         return mCharacteristics.getBoolean(KEY_SUPPORT_SUSPENSION);
188     }
189 
190     /** @hide */
191     @IntDef(flag = true, prefix = { "WIFI_AWARE_CIPHER_SUITE_" }, value = {
192             WIFI_AWARE_CIPHER_SUITE_NONE,
193             WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
194             WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
195             WIFI_AWARE_CIPHER_SUITE_NCS_PK_128,
196             WIFI_AWARE_CIPHER_SUITE_NCS_PK_256,
197     })
198     @Retention(RetentionPolicy.SOURCE)
199     public @interface WifiAwareDataPathCipherSuites {}
200 
201     /**
202      * Wi-Fi Aware supported open (unencrypted) data-path.
203      */
204     public static final int WIFI_AWARE_CIPHER_SUITE_NONE = 0;
205     /**
206      * Wi-Fi Aware supported cipher suite representing NCS SK 128: 128 bit shared-key.
207      */
208     public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1 << 0;
209 
210     /**
211      * Wi-Fi Aware supported cipher suite representing NCS SK 256: 256 bit shared-key.
212      */
213     public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 1 << 1;
214 
215     /**
216      * Wi-Fi Aware supported cipher suite representing NCS PK 2WDH 128: 128 bit public-key.
217      */
218     public static final int WIFI_AWARE_CIPHER_SUITE_NCS_PK_128 = 1 << 2;
219 
220     /**
221      * Wi-Fi Aware supported cipher suite representing NCS 2WDH 256: 256 bit public-key.
222      */
223     public static final int WIFI_AWARE_CIPHER_SUITE_NCS_PK_256 = 1 << 3;
224 
225     /**
226      * Wi-Fi Aware supported cipher suite representing NCS PASN 128: 128 bit public-key.
227      */
228     public static final int WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128 = 1 << 4;
229 
230     /**
231      * Wi-Fi Aware supported cipher suite representing NCS PASN 256: 256 bit public-key.
232      */
233     public static final int WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_256 = 1 << 5;
234 
235     /** @hide */
236     @IntDef(flag = true, prefix = { "WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_" }, value = {
237             WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128,
238             WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_256
239     })
240     @Retention(RetentionPolicy.SOURCE)
241     public @interface WifiAwarePairingCipherSuites {}
242 
243     /**
244      * Returns the set of cipher suites supported by the device for use in Wi-Fi Aware data-paths.
245      * The device automatically picks the strongest cipher suite when initiating a data-path setup.
246      *
247      * @return A set of flags from {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_128},
248      * {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_256}, {@link #WIFI_AWARE_CIPHER_SUITE_NCS_PK_128},
249      * or {@link #WIFI_AWARE_CIPHER_SUITE_NCS_PK_256}
250      */
getSupportedCipherSuites()251     public @WifiAwareDataPathCipherSuites int getSupportedCipherSuites() {
252         return mCharacteristics.getInt(KEY_SUPPORTED_DATA_PATH_CIPHER_SUITES);
253     }
254 
255     /**
256      * Returns the set of cipher suites supported by the device for use in Wi-Fi Aware pairing.
257      *
258      * @return A set of flags from {@link #WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_256},
259      * or {@link #WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_256}
260      */
getSupportedPairingCipherSuites()261     public @WifiAwarePairingCipherSuites int getSupportedPairingCipherSuites() {
262         return mCharacteristics.getInt(KEY_SUPPORTED_PAIRING_CIPHER_SUITES);
263     }
264 
265     @Override
writeToParcel(Parcel dest, int flags)266     public void writeToParcel(Parcel dest, int flags) {
267         dest.writeBundle(mCharacteristics);
268     }
269 
270     @Override
describeContents()271     public int describeContents() {
272         return 0;
273     }
274 
275     public static final @android.annotation.NonNull Creator<Characteristics> CREATOR =
276             new Creator<Characteristics>() {
277                 @Override
278                 public Characteristics createFromParcel(Parcel in) {
279                     Characteristics c = new Characteristics(in.readBundle());
280                     return c;
281                 }
282 
283                 @Override
284                 public Characteristics[] newArray(int size) {
285                     return new Characteristics[size];
286                 }
287             };
288 }
289