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
17package android.net;
18
19import android.annotation.SystemApi;
20import android.os.Parcel;
21import android.os.Parcelable;
22
23import java.util.Objects;
24import java.util.regex.Pattern;
25
26/**
27 * Information identifying a Wi-Fi network.
28 * @see NetworkKey
29 *
30 * @hide
31 */
32@SystemApi
33public class WifiKey implements Parcelable {
34
35    // Patterns used for validation.
36    private static final Pattern SSID_PATTERN = Pattern.compile("(\".*\")|(0x[\\p{XDigit}]+)",
37            Pattern.DOTALL);
38    private static final Pattern BSSID_PATTERN =
39            Pattern.compile("([\\p{XDigit}]{2}:){5}[\\p{XDigit}]{2}");
40
41    /**
42     * The service set identifier (SSID) of an 802.11 network. If the SSID can be decoded as
43     * UTF-8, it will be surrounded by double quotation marks. Otherwise, it will be a string of
44     * hex digits starting with 0x.
45     */
46    public final String ssid;
47
48    /**
49     * The basic service set identifier (BSSID) of an access point for this network. This will
50     * be in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}, where each X is a
51     * hexadecimal digit.
52     */
53    public final String bssid;
54
55    /**
56     * Construct a new {@link WifiKey} for the given Wi-Fi SSID/BSSID pair.
57     *
58     * @param ssid the service set identifier (SSID) of an 802.11 network. If the SSID can be
59     *         decoded as UTF-8, it should be surrounded by double quotation marks. Otherwise,
60     *         it should be a string of hex digits starting with 0x.
61     * @param bssid the basic service set identifier (BSSID) of this network's access point.
62     *         This should be in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX},
63     *         where each X is a hexadecimal digit.
64     * @throws IllegalArgumentException if either the SSID or BSSID is invalid.
65     */
66    public WifiKey(String ssid, String bssid) {
67        if (ssid == null || !SSID_PATTERN.matcher(ssid).matches()) {
68            throw new IllegalArgumentException("Invalid ssid: " + ssid);
69        }
70        if (bssid == null || !BSSID_PATTERN.matcher(bssid).matches()) {
71            throw new IllegalArgumentException("Invalid bssid: " + bssid);
72        }
73        this.ssid = ssid;
74        this.bssid = bssid;
75    }
76
77    private WifiKey(Parcel in) {
78        ssid = in.readString();
79        bssid = in.readString();
80    }
81
82    @Override
83    public int describeContents() {
84        return 0;
85    }
86
87    @Override
88    public void writeToParcel(Parcel out, int flags) {
89        out.writeString(ssid);
90        out.writeString(bssid);
91    }
92
93    @Override
94    public boolean equals(Object o) {
95        if (this == o) return true;
96        if (o == null || getClass() != o.getClass()) return false;
97
98        WifiKey wifiKey = (WifiKey) o;
99
100        return Objects.equals(ssid, wifiKey.ssid) && Objects.equals(bssid, wifiKey.bssid);
101    }
102
103    @Override
104    public int hashCode() {
105        return Objects.hash(ssid, bssid);
106    }
107
108    @Override
109    public String toString() {
110        return "WifiKey[SSID=" + ssid + ",BSSID=" + bssid + "]";
111    }
112
113    public static final Creator<WifiKey> CREATOR =
114            new Creator<WifiKey>() {
115                @Override
116                public WifiKey createFromParcel(Parcel in) {
117                    return new WifiKey(in);
118                }
119
120                @Override
121                public WifiKey[] newArray(int size) {
122                    return new WifiKey[size];
123                }
124            };
125}
126