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