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