1dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson/*
2dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * Copyright (C) 2014 The Android Open Source Project
3dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson *
4dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * Licensed under the Apache License, Version 2.0 (the "License");
5dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * you may not use this file except in compliance with the License.
6dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * You may obtain a copy of the License at
7dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson *
8dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson *      http://www.apache.org/licenses/LICENSE-2.0
9dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson *
10dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * Unless required by applicable law or agreed to in writing, software
11dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * distributed under the License is distributed on an "AS IS" BASIS,
12dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * See the License for the specific language governing permissions and
14dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * limitations under the License
15dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson */
16dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
17dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidsonpackage android.net;
18dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
197be8e9725f4a60f0d1a6cb175a05a320968d7439Jeff Davidsonimport android.annotation.SystemApi;
20dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidsonimport android.os.Parcel;
21dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidsonimport android.os.Parcelable;
22dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
236a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidsonimport java.util.Objects;
24dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidsonimport java.util.regex.Pattern;
25dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
26dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson/**
27dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * Information identifying a Wi-Fi network.
28dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * @see NetworkKey
29dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson *
30dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson * @hide
31dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson */
327be8e9725f4a60f0d1a6cb175a05a320968d7439Jeff Davidson@SystemApi
33dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidsonpublic class WifiKey implements Parcelable {
34dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
35dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    // Patterns used for validation.
361fb8a8f901d3479eb365eee17836e26d9137243eJeff Davidson    private static final Pattern SSID_PATTERN = Pattern.compile("(\".*\")|(0x[\\p{XDigit}]+)",
371fb8a8f901d3479eb365eee17836e26d9137243eJeff Davidson            Pattern.DOTALL);
38dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    private static final Pattern BSSID_PATTERN =
39dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson            Pattern.compile("([\\p{XDigit}]{2}:){5}[\\p{XDigit}]{2}");
40dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
41dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    /**
42dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * The service set identifier (SSID) of an 802.11 network. If the SSID can be decoded as
43dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * UTF-8, it will be surrounded by double quotation marks. Otherwise, it will be a string of
44dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * hex digits starting with 0x.
45dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     */
46dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    public final String ssid;
47dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
48dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    /**
49dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * The basic service set identifier (BSSID) of an access point for this network. This will
50dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * be in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}, where each X is a
51dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * hexadecimal digit.
52dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     */
53dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    public final String bssid;
54dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
55dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    /**
56dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * Construct a new {@link WifiKey} for the given Wi-Fi SSID/BSSID pair.
57dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     *
58dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * @param ssid the service set identifier (SSID) of an 802.11 network. If the SSID can be
59dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     *         decoded as UTF-8, it should be surrounded by double quotation marks. Otherwise,
60dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     *         it should be a string of hex digits starting with 0x.
61dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * @param bssid the basic service set identifier (BSSID) of this network's access point.
62dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     *         This should be in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX},
63dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     *         where each X is a hexadecimal digit.
64dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     * @throws IllegalArgumentException if either the SSID or BSSID is invalid.
65dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson     */
66dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    public WifiKey(String ssid, String bssid) {
67e925aeacab9a9fb4637d2ec6d850bffa7228e050Jeremy Joslin        if (ssid == null || !SSID_PATTERN.matcher(ssid).matches()) {
68dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson            throw new IllegalArgumentException("Invalid ssid: " + ssid);
69dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        }
70e925aeacab9a9fb4637d2ec6d850bffa7228e050Jeremy Joslin        if (bssid == null || !BSSID_PATTERN.matcher(bssid).matches()) {
71dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson            throw new IllegalArgumentException("Invalid bssid: " + bssid);
72dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        }
73dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        this.ssid = ssid;
74dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        this.bssid = bssid;
75dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    }
76dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
77dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    private WifiKey(Parcel in) {
78dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        ssid = in.readString();
79dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        bssid = in.readString();
80dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    }
81dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
82dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    @Override
83dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    public int describeContents() {
84dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        return 0;
85dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    }
86dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
87dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    @Override
88dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    public void writeToParcel(Parcel out, int flags) {
89dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        out.writeString(ssid);
90dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        out.writeString(bssid);
91dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    }
92dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
93dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    @Override
946a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson    public boolean equals(Object o) {
956a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson        if (this == o) return true;
966a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson        if (o == null || getClass() != o.getClass()) return false;
976a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson
986a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson        WifiKey wifiKey = (WifiKey) o;
996a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson
1006a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson        return Objects.equals(ssid, wifiKey.ssid) && Objects.equals(bssid, wifiKey.bssid);
1016a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson    }
1026a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson
1036a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson    @Override
1046a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson    public int hashCode() {
1056a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson        return Objects.hash(ssid, bssid);
1066a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson    }
1076a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson
1086a4b220f1263d95fdefe6361c2bc87bbb04bbed0Jeff Davidson    @Override
109dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    public String toString() {
110dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson        return "WifiKey[SSID=" + ssid + ",BSSID=" + bssid + "]";
111dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    }
112dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
113dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson    public static final Creator<WifiKey> CREATOR =
114dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson            new Creator<WifiKey>() {
115dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson                @Override
116dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson                public WifiKey createFromParcel(Parcel in) {
117dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson                    return new WifiKey(in);
118dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson                }
119dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson
120dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson                @Override
121dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson                public WifiKey[] newArray(int size) {
122dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson                    return new WifiKey[size];
123dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson                }
124dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson            };
125dc960e21ef1005fab5ef145773ddd6f40c802217Jeff Davidson}
126