• 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.hotspot2.pps;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.text.TextUtils;
24 import android.util.Log;
25 
26 import java.nio.charset.StandardCharsets;
27 import java.util.Arrays;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.Objects;
33 
34 /**
35  * Class representing HomeSP subtree in PerProviderSubscription (PPS)
36  * Management Object (MO) tree.
37  *
38  * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
39  * Release 2 Technical Specification.
40  */
41 public final class HomeSp implements Parcelable {
42     private static final String TAG = "HomeSp";
43 
44     /**
45      * Maximum number of bytes allowed for a SSID.
46      */
47     private static final int MAX_SSID_BYTES = 32;
48 
49     /**
50      * Integer value used for indicating null value in the Parcel.
51      */
52     private static final int NULL_VALUE = -1;
53 
54     /**
55      * FQDN (Fully Qualified Domain Name) of this home service provider.
56      */
57     private String mFqdn = null;
58     /**
59      * Set the FQDN (Fully Qualified Domain Name) associated with this home service provider.
60      *
61      * @param fqdn The FQDN to set to
62      */
setFqdn(String fqdn)63     public void setFqdn(String fqdn) {
64         mFqdn = fqdn;
65     }
66     /**
67      * Get the FQDN (Fully Qualified Domain Name) associated with this home service provider.
68      *
69      * @return the FQDN associated with this home service provider
70      */
getFqdn()71     public String getFqdn() {
72         return mFqdn;
73     }
74 
75     /**
76      * Friendly name of this home service provider.
77      */
78     private String mFriendlyName = null;
79     /**
80      * Set the friendly name associated with this home service provider.
81      *
82      * @param friendlyName The friendly name to set to
83      */
setFriendlyName(String friendlyName)84     public void setFriendlyName(String friendlyName) {
85         mFriendlyName = friendlyName;
86     }
87     /**
88      * Get the friendly name associated with this home service provider.
89      *
90      * @return the friendly name associated with this home service provider
91      */
getFriendlyName()92     public String getFriendlyName() {
93         return mFriendlyName;
94     }
95 
96     /**
97      * Icon URL of this home service provider.
98      */
99     private String mIconUrl = null;
100     /**
101      * @hide
102      */
setIconUrl(String iconUrl)103     public void setIconUrl(String iconUrl) {
104         mIconUrl = iconUrl;
105     }
106     /**
107      * @hide
108      */
getIconUrl()109     public String getIconUrl() {
110         return mIconUrl;
111     }
112 
113     /**
114      * <SSID, HESSID> duple of the networks that are consider home networks.
115      *
116      * According to the Section 9.1.2 of the Hotspot 2.0 Release 2 Technical Specification,
117      * all nodes in the PSS MO are encoded using UTF-8 unless stated otherwise.  Thus, the SSID
118      * string is assumed to be encoded using UTF-8.
119      */
120     private Map<String, Long> mHomeNetworkIds = null;
121     /**
122      * @hide
123      */
setHomeNetworkIds(Map<String, Long> homeNetworkIds)124     public void setHomeNetworkIds(Map<String, Long> homeNetworkIds) {
125         mHomeNetworkIds = homeNetworkIds;
126     }
127     /**
128      * @hide
129      */
getHomeNetworkIds()130     public Map<String, Long> getHomeNetworkIds() {
131         return mHomeNetworkIds;
132     }
133 
134     /**
135      * Used for determining if this provider is a member of a given Hotspot provider.
136      * Every Organization Identifiers (OIs) in this list are required to match an OI in the
137      * the Roaming Consortium advertised by a Hotspot, in order to consider this provider
138      * as a member of that Hotspot provider (e.g. successful authentication with such Hotspot
139      * is possible).
140      *
141      * Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
142      * (MO) tree for more detail.
143      */
144     private long[] mMatchAllOis = null;
145 
146     /**
147      * Set a list of HomeOIs such that all OIs in the list must match an OI in the Roaming
148      * Consortium advertised by a hotspot operator. The list set by this API will have precedence
149      * over {@link #setMatchAnyOis(long[])}, meaning the list set in {@link #setMatchAnyOis(long[])}
150      * will only be used for matching if the list set by this API is null or empty.
151      *
152      * @param matchAllOis An array of longs containing the HomeOIs
153      */
setMatchAllOis(@ullable long[] matchAllOis)154     public void setMatchAllOis(@Nullable long[] matchAllOis) {
155         mMatchAllOis = matchAllOis;
156     }
157 
158     /**
159      * Get the list of HomeOIs such that all OIs in the list must match an OI in the Roaming
160      * Consortium advertised by a hotspot operator.
161      *
162      * @return An array of longs containing the HomeOIs
163      */
getMatchAllOis()164     public @Nullable long[] getMatchAllOis() {
165         return mMatchAllOis;
166     }
167 
168     /**
169      * Used for determining if this provider is a member of a given Hotspot provider.
170      * Matching of any Organization Identifiers (OIs) in this list with an OI in the
171      * Roaming Consortium advertised by a Hotspot, will consider this provider as a member
172      * of that Hotspot provider (e.g. successful authentication with such Hotspot
173      * is possible).
174      *
175      * The list set by {@link #setMatchAllOis(long[])} will have precedence over this one, meaning
176      * this list will only be used for matching if the list set by {@link #setMatchAllOis(long[])}
177      * is null or empty.
178      *
179      * Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
180      * (MO) tree for more detail.
181      */
182     private long[] mMatchAnyOis = null;
183 
184     /**
185      * Set a list of HomeOIs such that any OI in the list matches an OI in the Roaming Consortium
186      * advertised by a hotspot operator. The list set by {@link #setMatchAllOis(long[])}
187      * will have precedence over this API, meaning this list will only be used for matching if the
188      * list set by {@link #setMatchAllOis(long[])} is null or empty.
189      *
190      * @param matchAnyOis An array of longs containing the HomeOIs
191      */
setMatchAnyOis(@ullable long[] matchAnyOis)192     public void setMatchAnyOis(@Nullable long[] matchAnyOis) {
193         mMatchAnyOis = matchAnyOis;
194     }
195 
196     /**
197      * Get a list of HomeOIs such that any OI in the list matches an OI in the Roaming Consortium
198      * advertised by a hotspot operator.
199      *
200      * @return An array of longs containing the HomeOIs
201      */
getMatchAnyOis()202     public @Nullable long[] getMatchAnyOis() {
203         return mMatchAnyOis;
204     }
205 
206     /**
207      * List of FQDN (Fully Qualified Domain Name) of partner providers.
208      * These providers should also be regarded as home Hotspot operators.
209      * This relationship is most likely achieved via a commercial agreement or
210      * operator merges between the providers.
211      */
212     private String[] mOtherHomePartners = null;
213 
214     /**
215      * Set the list of FQDN (Fully Qualified Domain Name) of other Home partner providers.
216      *
217      * @param otherHomePartners Array of Strings containing the FQDNs of other Home partner
218      *                         providers
219      * @hide
220      */
setOtherHomePartners(@ullable String[] otherHomePartners)221     public void setOtherHomePartners(@Nullable String[] otherHomePartners) {
222         mOtherHomePartners = otherHomePartners;
223     }
224 
225     /**
226      * Set the list of FQDN (Fully Qualified Domain Name) of other Home partner providers.
227      *
228      * @param otherHomePartners Collection of Strings containing the FQDNs of other Home partner
229      *                         providers
230      */
setOtherHomePartnersList(@onNull Collection<String> otherHomePartners)231     public void setOtherHomePartnersList(@NonNull Collection<String> otherHomePartners) {
232         if (otherHomePartners == null) {
233             return;
234         }
235         mOtherHomePartners = otherHomePartners.toArray(new String[otherHomePartners.size()]);
236     }
237 
238     /**
239      * Get the list of FQDN (Fully Qualified Domain Name) of other Home partner providers set in
240      * the profile.
241      *
242      * @return Array of Strings containing the FQDNs of other Home partner providers set in the
243      * profile
244      * @hide
245      */
getOtherHomePartners()246     public @Nullable String[] getOtherHomePartners() {
247         return mOtherHomePartners;
248     }
249 
250     /**
251      * Get the list of FQDN (Fully Qualified Domain Name) of other Home partner providers set in
252      * the profile.
253      *
254      * @return Collection of Strings containing the FQDNs of other Home partner providers set in the
255      * profile
256      */
getOtherHomePartnersList()257     public @NonNull Collection<String> getOtherHomePartnersList() {
258         if (mOtherHomePartners == null) {
259             return Collections.emptyList();
260         }
261         return Arrays.asList(mOtherHomePartners);
262     }
263 
264     /**
265      * List of Organization Identifiers (OIs) identifying a roaming consortium of
266      * which this provider is a member.
267      */
268     private long[] mRoamingConsortiumOis = null;
269     /**
270      * Set the Organization Identifiers (OIs) identifying a roaming consortium of which this
271      * provider is a member.
272      *
273      * @param roamingConsortiumOis Array of roaming consortium OIs
274      */
setRoamingConsortiumOis(long[] roamingConsortiumOis)275     public void setRoamingConsortiumOis(long[] roamingConsortiumOis) {
276         mRoamingConsortiumOis = roamingConsortiumOis;
277     }
278     /**
279      * Get the Organization Identifiers (OIs) identifying a roaming consortium of which this
280      * provider is a member.
281      *
282      * @return array of roaming consortium OIs
283      */
getRoamingConsortiumOis()284     public long[] getRoamingConsortiumOis() {
285         return mRoamingConsortiumOis;
286     }
287 
288     /**
289      * Constructor for creating HomeSp with default values.
290      */
HomeSp()291     public HomeSp() {}
292 
293     /**
294      * Copy constructor.
295      *
296      * @param source The source to copy from
297      */
HomeSp(HomeSp source)298     public HomeSp(HomeSp source) {
299         if (source == null) {
300             return;
301         }
302         mFqdn = source.mFqdn;
303         mFriendlyName = source.mFriendlyName;
304         mIconUrl = source.mIconUrl;
305         if (source.mHomeNetworkIds != null) {
306             mHomeNetworkIds = Collections.unmodifiableMap(source.mHomeNetworkIds);
307         }
308         if (source.mMatchAllOis != null) {
309             mMatchAllOis = Arrays.copyOf(source.mMatchAllOis, source.mMatchAllOis.length);
310         }
311         if (source.mMatchAnyOis != null) {
312             mMatchAnyOis = Arrays.copyOf(source.mMatchAnyOis, source.mMatchAnyOis.length);
313         }
314         if (source.mOtherHomePartners != null) {
315             mOtherHomePartners = Arrays.copyOf(source.mOtherHomePartners,
316                     source.mOtherHomePartners.length);
317         }
318         if (source.mRoamingConsortiumOis != null) {
319             mRoamingConsortiumOis = Arrays.copyOf(source.mRoamingConsortiumOis,
320                     source.mRoamingConsortiumOis.length);
321         }
322     }
323 
324     @Override
describeContents()325     public int describeContents() {
326         return 0;
327     }
328 
329     @Override
writeToParcel(Parcel dest, int flags)330     public void writeToParcel(Parcel dest, int flags) {
331         dest.writeString(mFqdn);
332         dest.writeString(mFriendlyName);
333         dest.writeString(mIconUrl);
334         writeHomeNetworkIds(dest, mHomeNetworkIds);
335         dest.writeLongArray(mMatchAllOis);
336         dest.writeLongArray(mMatchAnyOis);
337         dest.writeStringArray(mOtherHomePartners);
338         dest.writeLongArray(mRoamingConsortiumOis);
339     }
340 
341     @Override
equals(Object thatObject)342     public boolean equals(Object thatObject) {
343         if (this == thatObject) {
344             return true;
345         }
346         if (!(thatObject instanceof HomeSp)) {
347             return false;
348         }
349         HomeSp that = (HomeSp) thatObject;
350 
351         return TextUtils.equals(mFqdn, that.mFqdn)
352                 && TextUtils.equals(mFriendlyName, that.mFriendlyName)
353                 && TextUtils.equals(mIconUrl, that.mIconUrl)
354                 && (mHomeNetworkIds == null ? that.mHomeNetworkIds == null
355                         : mHomeNetworkIds.equals(that.mHomeNetworkIds))
356                 && Arrays.equals(mMatchAllOis, that.mMatchAllOis)
357                 && Arrays.equals(mMatchAnyOis, that.mMatchAnyOis)
358                 && Arrays.equals(mOtherHomePartners, that.mOtherHomePartners)
359                 && Arrays.equals(mRoamingConsortiumOis, that.mRoamingConsortiumOis);
360     }
361 
362     @Override
hashCode()363     public int hashCode() {
364         return Objects.hash(mFqdn, mFriendlyName, mIconUrl,
365                 mHomeNetworkIds, Arrays.hashCode(mMatchAllOis),
366                 Arrays.hashCode(mMatchAnyOis), Arrays.hashCode(mOtherHomePartners),
367                 Arrays.hashCode(mRoamingConsortiumOis));
368     }
369 
370     /**
371      * Get a unique identifier for HomeSp. This identifier depends only on items that remain
372      * constant throughout the lifetime of a subscription.
373      *
374      * @hide
375      * @return a Unique identifier for a HomeSp object
376      */
getUniqueId()377     public int getUniqueId() {
378         return Objects.hash(mFqdn);
379     }
380 
381 
382     @Override
toString()383     public String toString() {
384         StringBuilder builder = new StringBuilder();
385         builder.append("FQDN: ").append(mFqdn).append("\n");
386         builder.append("FriendlyName: ").append(mFriendlyName).append("\n");
387         builder.append("IconURL: ").append(mIconUrl).append("\n");
388         builder.append("HomeNetworkIDs: ").append(mHomeNetworkIds).append("\n");
389         builder.append("MatchAllOIs: ").append(mMatchAllOis).append("\n");
390         builder.append("MatchAnyOIs: ").append(mMatchAnyOis).append("\n");
391         builder.append("OtherHomePartners: ").append(mOtherHomePartners).append("\n");
392         builder.append("RoamingConsortiumOIs: ").append(mRoamingConsortiumOis).append("\n");
393         return builder.toString();
394     }
395 
396     /**
397      * Validate HomeSp data.
398      *
399      * @return true on success or false on failure
400      * @hide
401      */
validate()402     public boolean validate() {
403         if (TextUtils.isEmpty(mFqdn)) {
404             Log.d(TAG, "Missing FQDN");
405             return false;
406         }
407         if (TextUtils.isEmpty(mFriendlyName)) {
408             Log.d(TAG, "Missing friendly name");
409             return false;
410         }
411         // Verify SSIDs specified in the NetworkID
412         if (mHomeNetworkIds != null) {
413             for (Map.Entry<String, Long> entry : mHomeNetworkIds.entrySet()) {
414                 if (entry.getKey() == null ||
415                         entry.getKey().getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
416                     Log.d(TAG, "Invalid SSID in HomeNetworkIDs");
417                     return false;
418                 }
419             }
420         }
421         return true;
422     }
423 
424     public static final @android.annotation.NonNull Creator<HomeSp> CREATOR =
425         new Creator<HomeSp>() {
426             @Override
427             public HomeSp createFromParcel(Parcel in) {
428                 HomeSp homeSp = new HomeSp();
429                 homeSp.setFqdn(in.readString());
430                 homeSp.setFriendlyName(in.readString());
431                 homeSp.setIconUrl(in.readString());
432                 homeSp.setHomeNetworkIds(readHomeNetworkIds(in));
433                 homeSp.setMatchAllOis(in.createLongArray());
434                 homeSp.setMatchAnyOis(in.createLongArray());
435                 homeSp.setOtherHomePartners(in.createStringArray());
436                 homeSp.setRoamingConsortiumOis(in.createLongArray());
437                 return homeSp;
438             }
439 
440             @Override
441             public HomeSp[] newArray(int size) {
442                 return new HomeSp[size];
443             }
444 
445             /**
446              * Helper function for reading a Home Network IDs map from a Parcel.
447              *
448              * @param in The Parcel to read from
449              * @return Map of home network IDs
450              */
451             private Map<String, Long> readHomeNetworkIds(Parcel in) {
452                 int size = in.readInt();
453                 if (size == NULL_VALUE) {
454                     return null;
455                 }
456                 Map<String, Long> networkIds = new HashMap<>(size);
457                 for (int i = 0; i < size; i++) {
458                     String key = in.readString();
459                     Long value = null;
460                     long readValue = in.readLong();
461                     if (readValue != NULL_VALUE) {
462                         value = Long.valueOf(readValue);
463                     }
464                     networkIds.put(key, value);
465                 }
466                 return networkIds;
467             }
468         };
469 
470     /**
471      * Helper function for writing Home Network IDs map to a Parcel.
472      *
473      * @param dest The Parcel to write to
474      * @param networkIds The map of home network IDs
475      */
writeHomeNetworkIds(Parcel dest, Map<String, Long> networkIds)476     private static void writeHomeNetworkIds(Parcel dest, Map<String, Long> networkIds) {
477         if (networkIds == null) {
478             dest.writeInt(NULL_VALUE);
479             return;
480         }
481         dest.writeInt(networkIds.size());
482         for (Map.Entry<String, Long> entry : networkIds.entrySet()) {
483             dest.writeString(entry.getKey());
484             if (entry.getValue() == null) {
485                 dest.writeLong(NULL_VALUE);
486             } else {
487                 dest.writeLong(entry.getValue());
488             }
489         }
490     }
491 }
492