• 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.nan;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 
22 import java.util.Arrays;
23 
24 /**
25  * Defines the data for a NAN subscribe session. Built using
26  * {@link SubscribeData.Builder}. Subscribe is done using
27  * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
28  * or
29  * {@link WifiNanSubscribeSession#subscribe(SubscribeData, SubscribeSettings)}.
30  * @hide PROPOSED_NAN_API
31  */
32 public class SubscribeData implements Parcelable {
33     /**
34      * @hide
35      */
36     public final String mServiceName;
37 
38     /**
39      * @hide
40      */
41     public final int mServiceSpecificInfoLength;
42 
43     /**
44      * @hide
45      */
46     public final byte[] mServiceSpecificInfo;
47 
48     /**
49      * @hide
50      */
51     public final int mTxFilterLength;
52 
53     /**
54      * @hide
55      */
56     public final byte[] mTxFilter;
57 
58     /**
59      * @hide
60      */
61     public final int mRxFilterLength;
62 
63     /**
64      * @hide
65      */
66     public final byte[] mRxFilter;
67 
SubscribeData(String serviceName, byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] txFilter, int txFilterLength, byte[] rxFilter, int rxFilterLength)68     private SubscribeData(String serviceName, byte[] serviceSpecificInfo,
69             int serviceSpecificInfoLength, byte[] txFilter, int txFilterLength, byte[] rxFilter,
70             int rxFilterLength) {
71         mServiceName = serviceName;
72         mServiceSpecificInfoLength = serviceSpecificInfoLength;
73         mServiceSpecificInfo = serviceSpecificInfo;
74         mTxFilterLength = txFilterLength;
75         mTxFilter = txFilter;
76         mRxFilterLength = rxFilterLength;
77         mRxFilter = rxFilter;
78     }
79 
80     @Override
toString()81     public String toString() {
82         return "SubscribeData [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
83                 + (new String(mServiceSpecificInfo, 0, mServiceSpecificInfoLength))
84                 + "', mTxFilter="
85                 + (new TlvBufferUtils.TlvIterable(0, 1, mTxFilter, mTxFilterLength)).toString()
86                 + ", mRxFilter="
87                 + (new TlvBufferUtils.TlvIterable(0, 1, mRxFilter, mRxFilterLength)).toString()
88                 + "']";
89     }
90 
91     @Override
describeContents()92     public int describeContents() {
93         return 0;
94     }
95 
96     @Override
writeToParcel(Parcel dest, int flags)97     public void writeToParcel(Parcel dest, int flags) {
98         dest.writeString(mServiceName);
99         dest.writeInt(mServiceSpecificInfoLength);
100         if (mServiceSpecificInfoLength != 0) {
101             dest.writeByteArray(mServiceSpecificInfo, 0, mServiceSpecificInfoLength);
102         }
103         dest.writeInt(mTxFilterLength);
104         if (mTxFilterLength != 0) {
105             dest.writeByteArray(mTxFilter, 0, mTxFilterLength);
106         }
107         dest.writeInt(mRxFilterLength);
108         if (mRxFilterLength != 0) {
109             dest.writeByteArray(mRxFilter, 0, mRxFilterLength);
110         }
111     }
112 
113     public static final Creator<SubscribeData> CREATOR = new Creator<SubscribeData>() {
114         @Override
115         public SubscribeData[] newArray(int size) {
116             return new SubscribeData[size];
117         }
118 
119         @Override
120         public SubscribeData createFromParcel(Parcel in) {
121             String serviceName = in.readString();
122             int ssiLength = in.readInt();
123             byte[] ssi = new byte[ssiLength];
124             if (ssiLength != 0) {
125                 in.readByteArray(ssi);
126             }
127             int txFilterLength = in.readInt();
128             byte[] txFilter = new byte[txFilterLength];
129             if (txFilterLength != 0) {
130                 in.readByteArray(txFilter);
131             }
132             int rxFilterLength = in.readInt();
133             byte[] rxFilter = new byte[rxFilterLength];
134             if (rxFilterLength != 0) {
135                 in.readByteArray(rxFilter);
136             }
137 
138             return new SubscribeData(serviceName, ssi, ssiLength, txFilter, txFilterLength,
139                     rxFilter, rxFilterLength);
140         }
141     };
142 
143     @Override
equals(Object o)144     public boolean equals(Object o) {
145         if (this == o) {
146             return true;
147         }
148 
149         if (!(o instanceof SubscribeData)) {
150             return false;
151         }
152 
153         SubscribeData lhs = (SubscribeData) o;
154 
155         if (!mServiceName.equals(lhs.mServiceName)
156                 || mServiceSpecificInfoLength != lhs.mServiceSpecificInfoLength
157                 || mTxFilterLength != lhs.mTxFilterLength
158                 || mRxFilterLength != lhs.mRxFilterLength) {
159             return false;
160         }
161 
162         if (mServiceSpecificInfo != null && lhs.mServiceSpecificInfo != null) {
163             for (int i = 0; i < mServiceSpecificInfoLength; ++i) {
164                 if (mServiceSpecificInfo[i] != lhs.mServiceSpecificInfo[i]) {
165                     return false;
166                 }
167             }
168         } else if (mServiceSpecificInfoLength != 0) {
169             return false; // invalid != invalid
170         }
171 
172         if (mTxFilter != null && lhs.mTxFilter != null) {
173             for (int i = 0; i < mTxFilterLength; ++i) {
174                 if (mTxFilter[i] != lhs.mTxFilter[i]) {
175                     return false;
176                 }
177             }
178         } else if (mTxFilterLength != 0) {
179             return false; // invalid != invalid
180         }
181 
182         if (mRxFilter != null && lhs.mRxFilter != null) {
183             for (int i = 0; i < mRxFilterLength; ++i) {
184                 if (mRxFilter[i] != lhs.mRxFilter[i]) {
185                     return false;
186                 }
187             }
188         } else if (mRxFilterLength != 0) {
189             return false; // invalid != invalid
190         }
191 
192         return true;
193     }
194 
195     @Override
hashCode()196     public int hashCode() {
197         int result = 17;
198 
199         result = 31 * result + mServiceName.hashCode();
200         result = 31 * result + mServiceSpecificInfoLength;
201         result = 31 * result + Arrays.hashCode(mServiceSpecificInfo);
202         result = 31 * result + mTxFilterLength;
203         result = 31 * result + Arrays.hashCode(mTxFilter);
204         result = 31 * result + mRxFilterLength;
205         result = 31 * result + Arrays.hashCode(mRxFilter);
206 
207         return result;
208     }
209 
210     /**
211      * Builder used to build {@link SubscribeData} objects.
212      */
213     public static final class Builder {
214         private String mServiceName;
215         private int mServiceSpecificInfoLength;
216         private byte[] mServiceSpecificInfo = new byte[0];
217         private int mTxFilterLength;
218         private byte[] mTxFilter = new byte[0];
219         private int mRxFilterLength;
220         private byte[] mRxFilter = new byte[0];
221 
222         /**
223          * Specify the service name of the subscribe session. The actual on-air
224          * value is a 6 byte hashed representation of this string.
225          *
226          * @param serviceName The service name for the subscribe session.
227          * @return The builder to facilitate chaining
228          *         {@code builder.setXXX(..).setXXX(..)}.
229          */
setServiceName(String serviceName)230         public Builder setServiceName(String serviceName) {
231             mServiceName = serviceName;
232             return this;
233         }
234 
235         /**
236          * Specify service specific information for the subscribe session. This
237          * is a free-form byte array available to the application to send
238          * additional information as part of the discovery operation - i.e. it
239          * will not be used to determine whether a publish/subscribe match
240          * occurs.
241          *
242          * @param serviceSpecificInfo A byte-array for the service-specific
243          *            information field.
244          * @param serviceSpecificInfoLength The length of the byte-array to be
245          *            used.
246          * @return The builder to facilitate chaining
247          *         {@code builder.setXXX(..).setXXX(..)}.
248          */
setServiceSpecificInfo(byte[] serviceSpecificInfo, int serviceSpecificInfoLength)249         public Builder setServiceSpecificInfo(byte[] serviceSpecificInfo,
250                 int serviceSpecificInfoLength) {
251             mServiceSpecificInfoLength = serviceSpecificInfoLength;
252             mServiceSpecificInfo = serviceSpecificInfo;
253             return this;
254         }
255 
256         /**
257          * Specify service specific information for the subscribe session - same
258          * as {@link SubscribeData.Builder#setServiceSpecificInfo(byte[], int)}
259          * but obtaining the data from a String.
260          *
261          * @param serviceSpecificInfoStr The service specific information string
262          *            to be included (as a byte array) in the subscribe
263          *            information.
264          * @return The builder to facilitate chaining
265          *         {@code builder.setXXX(..).setXXX(..)}.
266          */
setServiceSpecificInfo(String serviceSpecificInfoStr)267         public Builder setServiceSpecificInfo(String serviceSpecificInfoStr) {
268             mServiceSpecificInfoLength = serviceSpecificInfoStr.length();
269             mServiceSpecificInfo = serviceSpecificInfoStr.getBytes();
270             return this;
271         }
272 
273         /**
274          * The transmit filter for an active subscribe session
275          * {@link SubscribeSettings.Builder#setSubscribeType(int)} and
276          * {@link SubscribeSettings#SUBSCRIBE_TYPE_ACTIVE}. Included in
277          * transmitted subscribe packets and used by receivers (passive
278          * publishers) to determine whether they match - in addition to just
279          * relying on the service name.
280          * <p>
281          * Format is an LV byte array - the {@link TlvBufferUtils} utility class
282          * is available to form and parse.
283          *
284          * @param txFilter The byte-array containing the LV formatted transmit
285          *            filter.
286          * @param txFilterLength The number of bytes in the transmit filter
287          *            argument.
288          * @return The builder to facilitate chaining
289          *         {@code builder.setXXX(..).setXXX(..)}.
290          */
setTxFilter(byte[] txFilter, int txFilterLength)291         public Builder setTxFilter(byte[] txFilter, int txFilterLength) {
292             mTxFilter = txFilter;
293             mTxFilterLength = txFilterLength;
294             return this;
295         }
296 
297         /**
298          * The transmit filter for a passive subsribe session
299          * {@link SubscribeSettings.Builder#setSubscribeType(int)} and
300          * {@link SubscribeSettings#SUBSCRIBE_TYPE_PASSIVE}. Used by the
301          * subscriber to determine whether they match transmitted publish
302          * packets - in addition to just relying on the service name.
303          * <p>
304          * Format is an LV byte array - the {@link TlvBufferUtils} utility class
305          * is available to form and parse.
306          *
307          * @param rxFilter The byte-array containing the LV formatted receive
308          *            filter.
309          * @param rxFilterLength The number of bytes in the receive filter
310          *            argument.
311          * @return The builder to facilitate chaining
312          *         {@code builder.setXXX(..).setXXX(..)}.
313          */
setRxFilter(byte[] rxFilter, int rxFilterLength)314         public Builder setRxFilter(byte[] rxFilter, int rxFilterLength) {
315             mRxFilter = rxFilter;
316             mRxFilterLength = rxFilterLength;
317             return this;
318         }
319 
320         /**
321          * Build {@link SubscribeData} given the current requests made on the
322          * builder.
323          */
build()324         public SubscribeData build() {
325             return new SubscribeData(mServiceName, mServiceSpecificInfo, mServiceSpecificInfoLength,
326                     mTxFilter, mTxFilterLength, mRxFilter, mRxFilterLength);
327         }
328     }
329 }
330