summaryrefslogtreecommitdiffstats
path: root/service/java/com/android/server/wifi/ScanResultMatchInfo.java
blob: b3d10cc386d71532a2200ef4475ded1b3884bf31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.wifi;

import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;

import com.android.server.wifi.util.ScanResultUtil;

import java.util.Objects;

/**
 * Class to store the info needed to match a scan result to the provided network configuration.
 */
public class ScanResultMatchInfo {
    /**
     * SSID of the network.
     */
    public String networkSsid;
    /**
     * Security Type of the network.
     */
    public @WifiConfiguration.SecurityType int networkType;
    /**
     * Special flag for PSK-SAE in transition mode
     */
    public boolean pskSaeInTransitionMode;
    /**
     * Special flag for OWE in transition mode
     */
    public boolean oweInTransitionMode;

    /**
     * Fetch network type from network configuration.
     */
    public static @WifiConfiguration.SecurityType int getNetworkType(WifiConfiguration config) {
        if (WifiConfigurationUtil.isConfigForSaeNetwork(config)) {
            return WifiConfiguration.SECURITY_TYPE_SAE;
        } else if (WifiConfigurationUtil.isConfigForPskNetwork(config)) {
            return WifiConfiguration.SECURITY_TYPE_PSK;
        } else if (WifiConfigurationUtil.isConfigForEapNetwork(config)) {
            return WifiConfiguration.SECURITY_TYPE_EAP;
        } else if (WifiConfigurationUtil.isConfigForEapSuiteBNetwork(config)) {
            return WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B;
        } else if (WifiConfigurationUtil.isConfigForWepNetwork(config)) {
            return WifiConfiguration.SECURITY_TYPE_WEP;
        } else if (WifiConfigurationUtil.isConfigForOweNetwork(config)) {
            return WifiConfiguration.SECURITY_TYPE_OWE;
        } else if (WifiConfigurationUtil.isConfigForOpenNetwork(config)) {
            return WifiConfiguration.SECURITY_TYPE_OPEN;
        }
        throw new IllegalArgumentException("Invalid WifiConfiguration: " + config);
    }

    /**
     * Get the ScanResultMatchInfo for the given WifiConfiguration
     */
    public static ScanResultMatchInfo fromWifiConfiguration(WifiConfiguration config) {
        ScanResultMatchInfo info = new ScanResultMatchInfo();
        info.networkSsid = config.SSID;
        info.networkType = getNetworkType(config);
        return info;
    }

    /**
     * Fetch network type from scan result.
     */
    public static @WifiConfiguration.SecurityType int getNetworkType(ScanResult scanResult) {
        if (ScanResultUtil.isScanResultForSaeNetwork(scanResult)) {
            return WifiConfiguration.SECURITY_TYPE_SAE;
        } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult)) {
            return WifiConfiguration.SECURITY_TYPE_PSK;
        } else if (ScanResultUtil.isScanResultForEapSuiteBNetwork(scanResult)) {
            return WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B;
        } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult)) {
            return WifiConfiguration.SECURITY_TYPE_EAP;
        } else if (ScanResultUtil.isScanResultForWepNetwork(scanResult)) {
            return WifiConfiguration.SECURITY_TYPE_WEP;
        } else if (ScanResultUtil.isScanResultForOweNetwork(scanResult)) {
            return WifiConfiguration.SECURITY_TYPE_OWE;
        } else if (ScanResultUtil.isScanResultForOpenNetwork(scanResult)) {
            return WifiConfiguration.SECURITY_TYPE_OPEN;
        } else {
            throw new IllegalArgumentException("Invalid ScanResult: " + scanResult);
        }
    }

    /**
     * Get the ScanResultMatchInfo for the given ScanResult
     */
    public static ScanResultMatchInfo fromScanResult(ScanResult scanResult) {
        ScanResultMatchInfo info = new ScanResultMatchInfo();
        // Scan result ssid's are not quoted, hence add quotes.
        // TODO: This matching algo works only if the scan result contains a string SSID.
        // However, according to our public documentation ths {@link WifiConfiguration#SSID} can
        // either have a hex string or quoted ASCII string SSID.
        info.networkSsid = ScanResultUtil.createQuotedSSID(scanResult.SSID);
        info.networkType = getNetworkType(scanResult);
        info.oweInTransitionMode = false;
        info.pskSaeInTransitionMode = false;
        if (info.networkType == WifiConfiguration.SECURITY_TYPE_SAE) {
            // Note that scan result util will always choose the highest security protocol.
            info.pskSaeInTransitionMode =
                    ScanResultUtil.isScanResultForPskSaeTransitionNetwork(scanResult);
        } else  if (info.networkType == WifiConfiguration.SECURITY_TYPE_OWE) {
            // Note that scan result util will always choose OWE.
            info.oweInTransitionMode =
                    ScanResultUtil.isScanResultForOweTransitionNetwork(scanResult);
        }
        return info;
    }

    @Override
    public boolean equals(Object otherObj) {
        if (this == otherObj) {
            return true;
        } else if (!(otherObj instanceof ScanResultMatchInfo)) {
            return false;
        }
        ScanResultMatchInfo other = (ScanResultMatchInfo) otherObj;
        if (!Objects.equals(networkSsid, other.networkSsid)) {
            return false;
        }
        boolean networkTypeEquals;

        // Detect <SSID, PSK+SAE> scan result and say it is equal to <SSID, PSK> configuration
        if (other.pskSaeInTransitionMode && networkType == WifiConfiguration.SECURITY_TYPE_PSK
                || (pskSaeInTransitionMode
                && other.networkType == WifiConfiguration.SECURITY_TYPE_PSK)) {
            networkTypeEquals = true;
        } else if ((networkType == WifiConfiguration.SECURITY_TYPE_OPEN
                && other.oweInTransitionMode) || (oweInTransitionMode
                && other.networkType == WifiConfiguration.SECURITY_TYPE_OPEN)) {
            // Special case we treat Enhanced Open and Open as equals. This is done to support the
            // case where a saved network is Open but we found an OWE in transition network.
            networkTypeEquals = true;
        } else {
            networkTypeEquals = networkType == other.networkType;
        }
        return networkTypeEquals;
    }

    @Override
    public int hashCode() {
        return Objects.hash(networkSsid);
    }

    @Override
    public String toString() {
        return "ScanResultMatchInfo: ssid: " + networkSsid + ", type: " + networkType;
    }
}