1 /*
2  * Copyright (C) 2014 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.passpoint;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 
22 import java.util.ArrayList;
23 import java.util.List;
24 
25 /** @hide */
26 public class WifiPasspointInfo implements Parcelable {
27 
28     /** TODO doc */
29     public static final int ANQP_CAPABILITY = 1 << 0;
30 
31     /** TODO doc */
32     public static final int VENUE_NAME = 1 << 1;
33 
34     /** TODO doc */
35     public static final int NETWORK_AUTH_TYPE = 1 << 2;
36 
37     /** TODO doc */
38     public static final int ROAMING_CONSORTIUM = 1 << 3;
39 
40     /** TODO doc */
41     public static final int IP_ADDR_TYPE_AVAILABILITY = 1 << 4;
42 
43     /** TODO doc */
44     public static final int NAI_REALM = 1 << 5;
45 
46     /** TODO doc */
47     public static final int CELLULAR_NETWORK = 1 << 6;
48 
49     /** TODO doc */
50     public static final int DOMAIN_NAME = 1 << 7;
51 
52     /** TODO doc */
53     public static final int HOTSPOT_CAPABILITY = 1 << 8;
54 
55     /** TODO doc */
56     public static final int OPERATOR_FRIENDLY_NAME = 1 << 9;
57 
58     /** TODO doc */
59     public static final int WAN_METRICS = 1 << 10;
60 
61     /** TODO doc */
62     public static final int CONNECTION_CAPABILITY = 1 << 11;
63 
64     /** TODO doc */
65     public static final int OSU_PROVIDER = 1 << 12;
66 
67     /** TODO doc */
68     public static final int PRESET_CRED_MATCH =
69             ANQP_CAPABILITY |
70                     HOTSPOT_CAPABILITY |
71                     NAI_REALM |
72                     CELLULAR_NETWORK |
73                     DOMAIN_NAME;
74 
75     /** TODO doc */
76     public static final int PRESET_ALL =
77             ANQP_CAPABILITY |
78                     VENUE_NAME |
79                     NETWORK_AUTH_TYPE |
80                     ROAMING_CONSORTIUM |
81                     IP_ADDR_TYPE_AVAILABILITY |
82                     NAI_REALM |
83                     CELLULAR_NETWORK |
84                     DOMAIN_NAME |
85                     HOTSPOT_CAPABILITY |
86                     OPERATOR_FRIENDLY_NAME |
87                     WAN_METRICS |
88                     CONNECTION_CAPABILITY |
89                     OSU_PROVIDER;
90 
91 
92     public static class WanMetrics {
93         public static final int STATUS_RESERVED = 0;
94         public static final int STATUS_UP = 1;
95         public static final int STATUS_DOWN = 2;
96         public static final int STATUS_TEST = 3;
97 
98         public int wanInfo;
99         public long downlinkSpeed;
100         public long uplinkSpeed;
101         public int downlinkLoad;
102         public int uplinkLoad;
103         public int lmd;
104 
getLinkStatus()105         public int getLinkStatus() {
106             return wanInfo & 0x3;
107         }
108 
getSymmetricLink()109         public boolean getSymmetricLink() {
110             return (wanInfo & (1 << 2)) != 0;
111         }
112 
getAtCapacity()113         public boolean getAtCapacity() {
114             return (wanInfo & (1 << 3)) != 0;
115         }
116 
117         @Override
toString()118         public String toString() {
119             return wanInfo + "," + downlinkSpeed + "," + uplinkSpeed + "," +
120                     downlinkLoad + "," + uplinkLoad + "," + lmd;
121         }
122     }
123 
124     public static class IpProtoPort {
125         public static final int STATUS_CLOSED = 0;
126         public static final int STATUS_OPEN = 1;
127         public static final int STATUS_UNKNOWN = 2;
128 
129         public int proto;
130         public int port;
131         public int status;
132 
133         @Override
toString()134         public String toString() {
135             return proto + "," + port + "," + status;
136         }
137     }
138 
139     public static class NetworkAuthType {
140         public static final int TYPE_TERMS_AND_CONDITION = 0;
141         public static final int TYPE_ONLINE_ENROLLMENT = 1;
142         public static final int TYPE_HTTP_REDIRECTION = 2;
143         public static final int TYPE_DNS_REDIRECTION = 3;
144 
145         public int type;
146         public String redirectUrl;
147 
148         @Override
toString()149         public String toString() {
150             return type + "," + redirectUrl;
151         }
152     }
153 
154     public static class IpAddressType {
155         public static final int IPV6_NOT_AVAILABLE = 0;
156         public static final int IPV6_AVAILABLE = 1;
157         public static final int IPV6_UNKNOWN = 2;
158 
159         public static final int IPV4_NOT_AVAILABLE = 0;
160         public static final int IPV4_PUBLIC = 1;
161         public static final int IPV4_PORT_RESTRICTED = 2;
162         public static final int IPV4_SINGLE_NAT = 3;
163         public static final int IPV4_DOUBLE_NAT = 4;
164         public static final int IPV4_PORT_RESTRICTED_SINGLE_NAT = 5;
165         public static final int IPV4_PORT_RESTRICTED_DOUBLE_NAT = 6;
166         public static final int IPV4_PORT_UNKNOWN = 7;
167 
168         private static final int NULL_VALUE = -1;
169 
170         public int availability;
171 
getIpv6Availability()172         public int getIpv6Availability() {
173             return availability & 0x3;
174         }
175 
getIpv4Availability()176         public int getIpv4Availability() {
177             return (availability & 0xFF) >> 2;
178         }
179 
180         @Override
toString()181         public String toString() {
182             return getIpv6Availability() + "," + getIpv4Availability();
183         }
184     }
185 
186     public static class NaiRealm {
187         public static final int ENCODING_RFC4282 = 0;
188         public static final int ENCODING_UTF8 = 1;
189 
190         public int encoding;
191         public String realm;
192 
193         @Override
toString()194         public String toString() {
195             return encoding + "," + realm;
196         }
197     }
198 
199     public static class CellularNetwork {
200         public String mcc;
201         public String mnc;
202 
203         @Override
toString()204         public String toString() {
205             return mcc + "," + mnc;
206         }
207     }
208 
209     /** BSSID */
210     public String bssid;
211 
212     /** venue name */
213     public String venueName;
214 
215     /** list of network authentication types */
216     public List<NetworkAuthType> networkAuthTypeList;
217 
218     /** list of roaming consortium OIs */
219     public List<String> roamingConsortiumList;
220 
221     /** IP address availability */
222     public IpAddressType ipAddrTypeAvailability;
223 
224     /** list of NAI realm */
225     public List<NaiRealm> naiRealmList;
226 
227     /** list of 3GPP cellular network */
228     public List<CellularNetwork> cellularNetworkList;
229 
230     /** list of fully qualified domain name (FQDN) */
231     public List<String> domainNameList;
232 
233     /** HS 2.0 operator friendly name */
234     public String operatorFriendlyName;
235 
236     /** HS 2.0 wan metrics */
237     public WanMetrics wanMetrics;
238 
239     /** list of HS 2.0 IP proto port */
240     public List<IpProtoPort> connectionCapabilityList;
241 
242     /** list of HS 2.0 OSU providers */
243     public List<WifiPasspointOsuProvider> osuProviderList;
244 
245     /**
246      * Convert mask to ANQP subtypes, for supplicant command use.
247      *
248      * @param mask The ANQP subtypes mask.
249      * @return String of ANQP subtypes, good for supplicant command use
250      * @hide
251      */
toAnqpSubtypes(int mask)252     public static String toAnqpSubtypes(int mask) {
253         StringBuilder sb = new StringBuilder();
254         if ((mask & ANQP_CAPABILITY) != 0)
255             sb.append("257,");
256         if ((mask & VENUE_NAME) != 0)
257             sb.append("258,");
258         if ((mask & NETWORK_AUTH_TYPE) != 0)
259             sb.append("260,");
260         if ((mask & ROAMING_CONSORTIUM) != 0)
261             sb.append("261,");
262         if ((mask & IP_ADDR_TYPE_AVAILABILITY) != 0)
263             sb.append("262,");
264         if ((mask & NAI_REALM) != 0)
265             sb.append("263,");
266         if ((mask & CELLULAR_NETWORK) != 0)
267             sb.append("264,");
268         if ((mask & DOMAIN_NAME) != 0)
269             sb.append("268,");
270         if ((mask & HOTSPOT_CAPABILITY) != 0)
271             sb.append("hs20:2,");
272         if ((mask & OPERATOR_FRIENDLY_NAME) != 0)
273             sb.append("hs20:3,");
274         if ((mask & WAN_METRICS) != 0)
275             sb.append("hs20:4,");
276         if ((mask & CONNECTION_CAPABILITY) != 0)
277             sb.append("hs20:5,");
278         if ((mask & OSU_PROVIDER) != 0)
279             sb.append("hs20:8,");
280         if (sb.length() > 0)
281             sb.deleteCharAt(sb.length() - 1);
282         return sb.toString();
283     }
284 
285     @Override
toString()286     public String toString() {
287         StringBuffer sb = new StringBuffer();
288 
289         sb.append("BSSID: ").append("(").append(bssid).append(")");
290 
291         if (venueName != null)
292             sb.append(" venueName: ").append("(")
293               .append(venueName.replace("\n", "\\n")).append(")");
294 
295         if (networkAuthTypeList != null) {
296             sb.append(" networkAuthType: ");
297             for (NetworkAuthType auth : networkAuthTypeList)
298                 sb.append("(").append(auth.toString()).append(")");
299         }
300 
301         if (roamingConsortiumList != null) {
302             sb.append(" roamingConsortium: ");
303             for (String oi : roamingConsortiumList)
304                 sb.append("(").append(oi).append(")");
305         }
306 
307         if (ipAddrTypeAvailability != null) {
308             sb.append(" ipAddrTypeAvaibility: ").append("(")
309               .append(ipAddrTypeAvailability.toString()).append(")");
310         }
311 
312         if (naiRealmList != null) {
313             sb.append(" naiRealm: ");
314             for (NaiRealm realm : naiRealmList)
315                 sb.append("(").append(realm.toString()).append(")");
316         }
317 
318         if (cellularNetworkList != null) {
319             sb.append(" cellularNetwork: ");
320             for (CellularNetwork plmn : cellularNetworkList)
321                 sb.append("(").append(plmn.toString()).append(")");
322         }
323 
324         if (domainNameList != null) {
325             sb.append(" domainName: ");
326             for (String fqdn : domainNameList)
327                 sb.append("(").append(fqdn).append(")");
328         }
329 
330         if (operatorFriendlyName != null)
331             sb.append(" operatorFriendlyName: ").append("(")
332               .append(operatorFriendlyName).append(")");
333 
334         if (wanMetrics != null)
335             sb.append(" wanMetrics: ").append("(")
336               .append(wanMetrics.toString()).append(")");
337 
338         if (connectionCapabilityList != null) {
339             sb.append(" connectionCapability: ");
340             for (IpProtoPort ip : connectionCapabilityList)
341                 sb.append("(").append(ip.toString()).append(")");
342         }
343 
344         if (osuProviderList != null) {
345             sb.append(" osuProviderList: ");
346             for (WifiPasspointOsuProvider osu : osuProviderList)
347                 sb.append("(").append(osu.toString()).append(")");
348         }
349 
350         return sb.toString();
351     }
352 
353     /** Implement the Parcelable interface {@hide} */
354     @Override
writeToParcel(Parcel out, int flags)355     public void writeToParcel(Parcel out, int flags) {
356         out.writeString(bssid);
357         out.writeString(venueName);
358 
359         if (networkAuthTypeList == null) {
360             out.writeInt(0);
361         } else {
362             out.writeInt(networkAuthTypeList.size());
363             for (NetworkAuthType auth : networkAuthTypeList) {
364                 out.writeInt(auth.type);
365                 out.writeString(auth.redirectUrl);
366             }
367         }
368 
369         if (roamingConsortiumList == null) {
370             out.writeInt(0);
371         } else {
372             out.writeInt(roamingConsortiumList.size());
373             for (String oi : roamingConsortiumList)
374                 out.writeString(oi);
375         }
376 
377         if (ipAddrTypeAvailability == null) {
378             out.writeInt(IpAddressType.NULL_VALUE);
379         } else {
380             out.writeInt(ipAddrTypeAvailability.availability);
381         }
382 
383         if (naiRealmList == null) {
384             out.writeInt(0);
385         } else {
386             out.writeInt(naiRealmList.size());
387             for (NaiRealm realm : naiRealmList) {
388                 out.writeInt(realm.encoding);
389                 out.writeString(realm.realm);
390             }
391         }
392 
393         if (cellularNetworkList == null) {
394             out.writeInt(0);
395         } else {
396             out.writeInt(cellularNetworkList.size());
397             for (CellularNetwork plmn : cellularNetworkList) {
398                 out.writeString(plmn.mcc);
399                 out.writeString(plmn.mnc);
400             }
401         }
402 
403 
404         if (domainNameList == null) {
405             out.writeInt(0);
406         } else {
407             out.writeInt(domainNameList.size());
408             for (String fqdn : domainNameList)
409                 out.writeString(fqdn);
410         }
411 
412         out.writeString(operatorFriendlyName);
413 
414         if (wanMetrics == null) {
415             out.writeInt(0);
416         } else {
417             out.writeInt(1);
418             out.writeInt(wanMetrics.wanInfo);
419             out.writeLong(wanMetrics.downlinkSpeed);
420             out.writeLong(wanMetrics.uplinkSpeed);
421             out.writeInt(wanMetrics.downlinkLoad);
422             out.writeInt(wanMetrics.uplinkLoad);
423             out.writeInt(wanMetrics.lmd);
424         }
425 
426         if (connectionCapabilityList == null) {
427             out.writeInt(0);
428         } else {
429             out.writeInt(connectionCapabilityList.size());
430             for (IpProtoPort ip : connectionCapabilityList) {
431                 out.writeInt(ip.proto);
432                 out.writeInt(ip.port);
433                 out.writeInt(ip.status);
434             }
435         }
436 
437         if (osuProviderList == null) {
438             out.writeInt(0);
439         } else {
440             out.writeInt(osuProviderList.size());
441             for (WifiPasspointOsuProvider osu : osuProviderList)
442                 osu.writeToParcel(out, flags);
443         }
444     }
445 
446     /** Implement the Parcelable interface {@hide} */
447     @Override
describeContents()448     public int describeContents() {
449         return 0;
450     }
451 
452     /** Implement the Parcelable interface {@hide} */
453     public static final Parcelable.Creator<WifiPasspointInfo> CREATOR =
454             new Parcelable.Creator<WifiPasspointInfo>() {
455                 @Override
456                 public WifiPasspointInfo createFromParcel(Parcel in) {
457                     WifiPasspointInfo p = new WifiPasspointInfo();
458                     int n;
459 
460                     p.bssid = in.readString();
461                     p.venueName = in.readString();
462 
463                     n = in.readInt();
464                     if (n > 0) {
465                         p.networkAuthTypeList = new ArrayList<NetworkAuthType>();
466                         for (int i = 0; i < n; i++) {
467                             NetworkAuthType auth = new NetworkAuthType();
468                             auth.type = in.readInt();
469                             auth.redirectUrl = in.readString();
470                             p.networkAuthTypeList.add(auth);
471                         }
472                     }
473 
474                     n = in.readInt();
475                     if (n > 0) {
476                         p.roamingConsortiumList = new ArrayList<String>();
477                         for (int i = 0; i < n; i++)
478                             p.roamingConsortiumList.add(in.readString());
479                     }
480 
481                     n = in.readInt();
482                     if (n != IpAddressType.NULL_VALUE) {
483                         p.ipAddrTypeAvailability = new IpAddressType();
484                         p.ipAddrTypeAvailability.availability = n;
485                     }
486 
487                     n = in.readInt();
488                     if (n > 0) {
489                         p.naiRealmList = new ArrayList<NaiRealm>();
490                         for (int i = 0; i < n; i++) {
491                             NaiRealm realm = new NaiRealm();
492                             realm.encoding = in.readInt();
493                             realm.realm = in.readString();
494                             p.naiRealmList.add(realm);
495                         }
496                     }
497 
498                     n = in.readInt();
499                     if (n > 0) {
500                         p.cellularNetworkList = new ArrayList<CellularNetwork>();
501                         for (int i = 0; i < n; i++) {
502                             CellularNetwork plmn = new CellularNetwork();
503                             plmn.mcc = in.readString();
504                             plmn.mnc = in.readString();
505                             p.cellularNetworkList.add(plmn);
506                         }
507                     }
508 
509                     n = in.readInt();
510                     if (n > 0) {
511                         p.domainNameList = new ArrayList<String>();
512                         for (int i = 0; i < n; i++)
513                             p.domainNameList.add(in.readString());
514                     }
515 
516                     p.operatorFriendlyName = in.readString();
517 
518                     n = in.readInt();
519                     if (n > 0) {
520                         p.wanMetrics = new WanMetrics();
521                         p.wanMetrics.wanInfo = in.readInt();
522                         p.wanMetrics.downlinkSpeed = in.readLong();
523                         p.wanMetrics.uplinkSpeed = in.readLong();
524                         p.wanMetrics.downlinkLoad = in.readInt();
525                         p.wanMetrics.uplinkLoad = in.readInt();
526                         p.wanMetrics.lmd = in.readInt();
527                     }
528 
529                     n = in.readInt();
530                     if (n > 0) {
531                         p.connectionCapabilityList = new ArrayList<IpProtoPort>();
532                         for (int i = 0; i < n; i++) {
533                             IpProtoPort ip = new IpProtoPort();
534                             ip.proto = in.readInt();
535                             ip.port = in.readInt();
536                             ip.status = in.readInt();
537                             p.connectionCapabilityList.add(ip);
538                         }
539                     }
540 
541                     n = in.readInt();
542                     if (n > 0) {
543                         p.osuProviderList = new ArrayList<WifiPasspointOsuProvider>();
544                         for (int i = 0; i < n; i++) {
545                             WifiPasspointOsuProvider osu = WifiPasspointOsuProvider.CREATOR
546                                     .createFromParcel(in);
547                             p.osuProviderList.add(osu);
548                         }
549                     }
550 
551                     return p;
552                 }
553 
554                 @Override
555                 public WifiPasspointInfo[] newArray(int size) {
556                     return new WifiPasspointInfo[size];
557                 }
558             };
559 }
560