104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff/*
204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * Copyright (C) 2010 The Android Open Source Project
304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff *
404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License");
504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * you may not use this file except in compliance with the License.
604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * You may obtain a copy of the License at
704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff *
804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff *      http://www.apache.org/licenses/LICENSE-2.0
904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff *
1004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * Unless required by applicable law or agreed to in writing, software
1104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS,
1204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * See the License for the specific language governing permissions and
1404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * limitations under the License.
1504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff */
1604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffpackage android.net.wifi;
1804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffimport android.content.Context;
2004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffimport android.content.Intent;
210216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwaltimport android.net.DhcpInfoInternal;
2296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriffimport android.net.LinkAddress;
2396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriffimport android.net.LinkProperties;
2496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriffimport android.net.NetworkUtils;
25cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriffimport android.net.NetworkInfo.DetailedState;
26128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriffimport android.net.ProxyProperties;
27aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport android.net.RouteInfo;
28565f9f216aa87f11d451ae6532d5153001a386bfKenny Rootimport android.net.wifi.WifiConfiguration.EnterpriseField;
2931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriffimport android.net.wifi.WifiConfiguration.IpAssignment;
3031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriffimport android.net.wifi.WifiConfiguration.KeyMgmt;
31128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriffimport android.net.wifi.WifiConfiguration.ProxySettings;
3204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffimport android.net.wifi.WifiConfiguration.Status;
33be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriffimport android.net.wifi.NetworkUpdateResult;
345ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriffimport static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
3531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriffimport android.os.Environment;
36e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriffimport android.os.Message;
37e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriffimport android.os.Handler;
38e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriffimport android.os.HandlerThread;
395ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
4004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffimport android.text.TextUtils;
4104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffimport android.util.Log;
4204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
43128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriffimport java.io.BufferedInputStream;
44128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriffimport java.io.BufferedOutputStream;
45128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriffimport java.io.DataInputStream;
46128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriffimport java.io.DataOutputStream;
4796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriffimport java.io.EOFException;
4831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriffimport java.io.FileInputStream;
49128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriffimport java.io.FileOutputStream;
5031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriffimport java.io.IOException;
5196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriffimport java.net.InetAddress;
5296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriffimport java.net.UnknownHostException;
5304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffimport java.util.ArrayList;
5404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffimport java.util.BitSet;
5596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriffimport java.util.Collection;
5631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriffimport java.util.HashMap;
5796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriffimport java.util.Iterator;
5804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffimport java.util.List;
59e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriffimport java.util.concurrent.atomic.AtomicInteger;
6004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
6104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff/**
6204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * This class provides the API to manage configured
6304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * wifi networks. The API is not thread safe is being
6404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * used only from WifiStateMachine.
6504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff *
6604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * It deals with the following
6704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * - Add/update/remove a WifiConfiguration
6831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *   The configuration contains two types of information.
69128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *     = IP and proxy configuration that is handled by WifiConfigStore and
7031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *       is saved to disk on any change.
71128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *
72128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       The format of configuration file is as follows:
73128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       <version>
74128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       <netA_key1><netA_value1><netA_key2><netA_value2>...<EOS>
75128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       <netB_key1><netB_value1><netB_key2><netB_value2>...<EOS>
76128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       ..
77128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *
78128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       (key, value) pairs for a given network are grouped together and can
7996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff *       be in any order. A EOS at the end of a set of (key, value) pairs
80128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       indicates that the next set of (key, value) pairs are for a new
8196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff *       network. A network is identified by a unique ID_KEY. If there is no
8296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff *       ID_KEY in the (key, value) pairs, the data is discarded.
83128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *
84128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       An invalid version on read would result in discarding the contents of
85128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       the file. On the next write, the latest version is written to file.
86128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *
87128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       Any failures during read or write to the configuration file are ignored
88128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       without reporting to the user since the likelihood of these errors are
89128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *       low and the impact on connectivity is low.
90128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *
9131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *     = SSID & security details that is pushed to the supplicant.
9231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *       supplicant saves these details to the disk on calling
9331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *       saveConfigCommand().
9431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *
9531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *       We have two kinds of APIs exposed:
9631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *        > public API calls that provide fine grained control
9731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *          - enableNetwork, disableNetwork, addOrUpdateNetwork(),
9831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *          removeNetwork(). For these calls, the config is not persisted
9931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *          to the disk. (TODO: deprecate these calls in WifiManager)
10031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *        > The new API calls - selectNetwork(), saveNetwork() & forgetNetwork().
10131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *          These calls persist the supplicant config to disk.
102128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff *
10304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff * - Maintain a list of configured networks for quick access
10431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff *
10504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff */
10604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriffclass WifiConfigStore {
10704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
108fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private Context mContext;
10904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    private static final String TAG = "WifiConfigStore";
1107f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    private static final boolean DBG = false;
11104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
11231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    /* configured networks with network id as the key */
113fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private HashMap<Integer, WifiConfiguration> mConfiguredNetworks =
11431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            new HashMap<Integer, WifiConfiguration>();
11531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
11631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    /* A network id is a unique identifier for a network configured in the
11731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff     * supplicant. Network ids are generated when the supplicant reads
11831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff     * the configuration file at start and can thus change for networks.
11931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff     * We store the IP configuration for networks along with a unique id
12031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff     * that is generated from SSID and security type of the network. A mapping
12131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff     * from the generated unique id to network id of the network is needed to
12231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff     * map supplicant config to IP configuration. */
123fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private HashMap<Integer, Integer> mNetworkIds =
12431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            new HashMap<Integer, Integer>();
12531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
12604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /* Tracks the highest priority of configured networks */
127fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private int mLastPriority = -1;
12804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
12931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    private static final String ipConfigFile = Environment.getDataDirectory() +
13031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            "/misc/wifi/ipconfig.txt";
13131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
132aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    private static final int IPCONFIG_FILE_VERSION = 2;
13331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
13496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    /* IP and proxy configuration keys */
13596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String ID_KEY = "id";
13696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String IP_ASSIGNMENT_KEY = "ipAssignment";
13796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String LINK_ADDRESS_KEY = "linkAddress";
13896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String GATEWAY_KEY = "gateway";
13996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String DNS_KEY = "dns";
14096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String PROXY_SETTINGS_KEY = "proxySettings";
14196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String PROXY_HOST_KEY = "proxyHost";
14296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String PROXY_PORT_KEY = "proxyPort";
14396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String EXCLUSION_LIST_KEY = "exclusionList";
14496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    private static final String EOS = "eos";
14596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
146fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private WifiNative mWifiNative;
147fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff
148fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    WifiConfigStore(Context c, WifiNative wn) {
149fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mContext = c;
150fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative = wn;
151fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    }
152e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
15304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
154fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff     * Fetch the list of configured networks
15504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * and enable all stored networks in supplicant.
15604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
157fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    void initialize() {
1587f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        if (DBG) log("Loading config and enabling all networks");
1595ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff        loadConfiguredNetworks();
16004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        enableAllNetworks();
16104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
16204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
16304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
16404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Fetch the list of currently configured networks
16504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * @return List of networks
16604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
167fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    List<WifiConfiguration> getConfiguredNetworks() {
16804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
169fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        for(WifiConfiguration config : mConfiguredNetworks.values()) {
170e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            networks.add(new WifiConfiguration(config));
17104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
17204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return networks;
17304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
17404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
17504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
17604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * enable all networks and save config. This will be a no-op if the list
17704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * of configured networks indicates all networks as being enabled
17804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
179fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    void enableAllNetworks() {
1808e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff        boolean networkEnabledStateChanged = false;
181fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        for(WifiConfiguration config : mConfiguredNetworks.values()) {
182e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            if(config != null && config.status == Status.DISABLED) {
183fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                if(mWifiNative.enableNetwork(config.networkId, false)) {
184e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    networkEnabledStateChanged = true;
185e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    config.status = Status.ENABLED;
186e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                } else {
187e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    loge("Enable network failed on " + config.networkId);
18831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                }
18904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
19004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
19104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1928e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff        if (networkEnabledStateChanged) {
193fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.saveConfig();
1948e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff            sendConfiguredNetworksChangedBroadcast();
1958e86b89860114386e6c43f55fc034a26798b73e2Irfan Sheriff        }
19604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
19704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
19804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
19904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
20004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Selects the specified network for connection. This involves
20104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * updating the priority of all the networks and enabling the given
20204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * network while disabling others.
20304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     *
20404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Selecting a network will leave the other networks disabled and
20504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * a call to enableAllNetworks() needs to be issued upon a connection
20604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * or a failure event from supplicant
20704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     *
20804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * @param netId network to select for connection
209b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff     * @return false if the network id is invalid
21004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
211b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff    boolean selectNetwork(int netId) {
212b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff        if (netId == INVALID_NETWORK_ID) return false;
213b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff
21404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        // Reset the priority of each network at start or if it goes too high.
215fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if (mLastPriority == -1 || mLastPriority > 1000000) {
216fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            for(WifiConfiguration config : mConfiguredNetworks.values()) {
217e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                if (config.networkId != INVALID_NETWORK_ID) {
218e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    config.priority = 0;
219e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    addOrUpdateNetworkNative(config);
22004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                }
22104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
222fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mLastPriority = 0;
22304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
22404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
22504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        // Set to the highest priority and save the configuration.
22604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        WifiConfiguration config = new WifiConfiguration();
22704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        config.networkId = netId;
228fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        config.priority = ++mLastPriority;
22904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
23004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        addOrUpdateNetworkNative(config);
231fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.saveConfig();
23204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
23304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        /* Enable the given network while disabling all other networks */
23431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        enableNetworkWithoutBroadcast(netId, true);
23504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
23631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff       /* Avoid saving the config & sending a broadcast to prevent settings
23731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        * from displaying a disabled list of networks */
238b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff        return true;
23904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
24004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
24104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
24204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Add/update the specified configuration and save config
24304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     *
24404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * @param config WifiConfiguration to be saved
245d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return network update result
24604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
247fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    NetworkUpdateResult saveNetwork(WifiConfiguration config) {
248b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff        // A new network cannot have null SSID
249b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff        if (config == null || (config.networkId == INVALID_NETWORK_ID &&
250b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff                config.SSID == null)) {
251b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff            return new NetworkUpdateResult(INVALID_NETWORK_ID);
252b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff        }
253b3e96c527b8ac96e869bafeff5f7fab099e28396Irfan Sheriff
2545ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff        boolean newNetwork = (config.networkId == INVALID_NETWORK_ID);
255be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        NetworkUpdateResult result = addOrUpdateNetworkNative(config);
256be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        int netId = result.getNetworkId();
25704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        /* enable a new network */
2585ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff        if (newNetwork && netId != INVALID_NETWORK_ID) {
259fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.enableNetwork(netId, false);
260fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mConfiguredNetworks.get(netId).status = Status.ENABLED;
26104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
262fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.saveConfig();
2631b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        sendConfiguredNetworksChangedBroadcast(config, result.isNewNetwork() ?
2641b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                WifiManager.CHANGE_REASON_ADDED : WifiManager.CHANGE_REASON_CONFIG_CHANGE);
265be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return result;
26604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
26704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
268fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    void updateStatus(int netId, DetailedState state) {
269cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff        if (netId != INVALID_NETWORK_ID) {
270fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            WifiConfiguration config = mConfiguredNetworks.get(netId);
271cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff            if (config == null) return;
272cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff            switch (state) {
273cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff                case CONNECTED:
274cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff                    config.status = Status.CURRENT;
275cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff                    break;
276cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff                case DISCONNECTED:
27786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    //If network is already disabled, keep the status
27886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    if (config.status == Status.CURRENT) {
27986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        config.status = Status.ENABLED;
28086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    }
281cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff                    break;
282cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff                default:
283cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff                    //do nothing, retain the existing state
284cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff                    break;
285cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff            }
286cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff        }
287cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff    }
288cdc077c9dd6473b5abfad4edfaf1ff41a436caafIrfan Sheriff
28904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
29004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Forget the specified network and save config
29104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     *
29204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * @param netId network to forget
293d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return {@code true} if it succeeds, {@code false} otherwise
29404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
295d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    boolean forgetNetwork(int netId) {
296fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if (mWifiNative.removeNetwork(netId)) {
297fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.saveConfig();
2981b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            WifiConfiguration target = null;
299fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            WifiConfiguration config = mConfiguredNetworks.get(netId);
300e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            if (config != null) {
3011b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                target = mConfiguredNetworks.remove(netId);
302fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mNetworkIds.remove(configKey(config));
30331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            }
3041b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            if (target != null) {
3051b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                writeIpAndProxyConfigurations();
3061b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                sendConfiguredNetworksChangedBroadcast(target, WifiManager.CHANGE_REASON_REMOVED);
3071b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            }
308d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff            return true;
30931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        } else {
3107f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to remove network " + netId);
311d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff            return false;
31231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
31304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
31404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
31504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
31604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Add/update a network. Note that there is no saveConfig operation.
31704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * This function is retained for compatibility with the public
31804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * API. The more powerful saveNetwork() is used by the
31904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * state machine
32004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     *
32104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * @param config wifi configuration to add/update
322d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return network Id
32304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
324fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    int addOrUpdateNetwork(WifiConfiguration config) {
325be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        NetworkUpdateResult result = addOrUpdateNetworkNative(config);
3261b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        if (result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID) {
3271b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            sendConfiguredNetworksChangedBroadcast(mConfiguredNetworks.get(result.getNetworkId()),
3281b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                    result.isNewNetwork ? WifiManager.CHANGE_REASON_ADDED :
3291b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                        WifiManager.CHANGE_REASON_CONFIG_CHANGE);
3301b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        }
331be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return result.getNetworkId();
33204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
33304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
33404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
33504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Remove a network. Note that there is no saveConfig operation.
33604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * This function is retained for compatibility with the public
33704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * API. The more powerful forgetNetwork() is used by the
33804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * state machine for network removal
33904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     *
34004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * @param netId network to be removed
341d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return {@code true} if it succeeds, {@code false} otherwise
34204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
343fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    boolean removeNetwork(int netId) {
344fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        boolean ret = mWifiNative.removeNetwork(netId);
3451b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        WifiConfiguration config = null;
346e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        if (ret) {
3471b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            config = mConfiguredNetworks.get(netId);
348e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            if (config != null) {
3491b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                config = mConfiguredNetworks.remove(netId);
350fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mNetworkIds.remove(configKey(config));
3518fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy            }
35231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
3531b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        if (config != null) {
3541b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            sendConfiguredNetworksChangedBroadcast(config, WifiManager.CHANGE_REASON_REMOVED);
3551b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        }
35604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return ret;
35704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
35804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
35904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
36004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Enable a network. Note that there is no saveConfig operation.
36104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * This function is retained for compatibility with the public
36204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * API. The more powerful selectNetwork()/saveNetwork() is used by the
36304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * state machine for connecting to a network
36404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     *
3651b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood     * @param netId network to be enabled
366d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return {@code true} if it succeeds, {@code false} otherwise
36704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
368fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    boolean enableNetwork(int netId, boolean disableOthers) {
36931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        boolean ret = enableNetworkWithoutBroadcast(netId, disableOthers);
3701b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        if (disableOthers) {
3711b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            sendConfiguredNetworksChangedBroadcast();
3721b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        } else {
3731b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            WifiConfiguration enabledNetwork = null;
3741b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            synchronized(mConfiguredNetworks) {
3751b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                enabledNetwork = mConfiguredNetworks.get(netId);
3761b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            }
3771b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            // check just in case the network was removed by someone else.
3781b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            if (enabledNetwork != null) {
3791b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                sendConfiguredNetworksChangedBroadcast(enabledNetwork,
3801b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                        WifiManager.CHANGE_REASON_CONFIG_CHANGE);
3811b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            }
3821b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        }
38331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        return ret;
38431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    }
38531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
386fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    boolean enableNetworkWithoutBroadcast(int netId, boolean disableOthers) {
387fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        boolean ret = mWifiNative.enableNetwork(netId, disableOthers);
38831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
389fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        WifiConfiguration config = mConfiguredNetworks.get(netId);
390e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        if (config != null) config.status = Status.ENABLED;
39131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
39231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        if (disableOthers) {
3935ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff            markAllNetworksDisabledExcept(netId);
39431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
39504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return ret;
39604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
39704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
39804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
39904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Disable a network. Note that there is no saveConfig operation.
40004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * @param netId network to be disabled
401d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return {@code true} if it succeeds, {@code false} otherwise
40204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
403fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    boolean disableNetwork(int netId) {
4048dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy        return disableNetwork(netId, WifiConfiguration.DISABLED_UNKNOWN_REASON);
4058dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy    }
4068dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy
4078dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy    /**
4088dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy     * Disable a network. Note that there is no saveConfig operation.
4098dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy     * @param netId network to be disabled
4108dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy     * @param reason reason code network was disabled
411d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return {@code true} if it succeeds, {@code false} otherwise
4128dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy     */
413fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    boolean disableNetwork(int netId, int reason) {
414fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        boolean ret = mWifiNative.disableNetwork(netId);
4151b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        WifiConfiguration network = null;
416fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        WifiConfiguration config = mConfiguredNetworks.get(netId);
417e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        /* Only change the reason if the network was not previously disabled */
418e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        if (config != null && config.status != Status.DISABLED) {
419e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            config.status = Status.DISABLED;
420e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            config.disableReason = reason;
4211b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            network = config;
4221b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        }
4231b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        if (network != null) {
4241b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            sendConfiguredNetworksChangedBroadcast(network,
4251b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                    WifiManager.CHANGE_REASON_CONFIG_CHANGE);
42631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
42704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return ret;
42804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
42904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
43004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
43104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Save the configured networks in supplicant to disk
432d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return {@code true} if it succeeds, {@code false} otherwise
43304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
434fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    boolean saveConfig() {
435fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        return mWifiNative.saveConfig();
43604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
43704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
43831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    /**
439f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff     * Start WPS pin method configuration with pin obtained
440f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff     * from the access point
441d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @param config WPS configuration
442d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return Wps result containing status and pin
4435ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff     */
444fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    WpsResult startWpsWithPinFromAccessPoint(WpsInfo config) {
445e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        WpsResult result = new WpsResult();
446fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if (mWifiNative.startWpsRegistrar(config.BSSID, config.pin)) {
4475ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff            /* WPS leaves all networks disabled */
4485ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff            markAllNetworksDisabled();
449e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            result.status = WpsResult.Status.SUCCESS;
450e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        } else {
4517f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to start WPS pin method configuration");
452e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            result.status = WpsResult.Status.FAILURE;
4535ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff        }
454e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        return result;
4555ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
4565ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
4575ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    /**
458f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff     * Start WPS pin method configuration with pin obtained
459f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff     * from the device
460e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff     * @return WpsResult indicating status and pin
461f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff     */
462fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    WpsResult startWpsWithPinFromDevice(WpsInfo config) {
463e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        WpsResult result = new WpsResult();
464fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        result.pin = mWifiNative.startWpsPinDisplay(config.BSSID);
465f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        /* WPS leaves all networks disabled */
466e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        if (!TextUtils.isEmpty(result.pin)) {
467f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff            markAllNetworksDisabled();
468e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            result.status = WpsResult.Status.SUCCESS;
469f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        } else {
4707f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to start WPS pin method configuration");
471e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            result.status = WpsResult.Status.FAILURE;
472f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff        }
473e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        return result;
474f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff    }
475f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff
476f235c5ab91b040b88ceb61beb819e15f1b19e9e4Irfan Sheriff    /**
4775ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff     * Start WPS push button configuration
478d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @param config WPS configuration
479d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return WpsResult indicating status and pin
4805ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff     */
481fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    WpsResult startWpsPbc(WpsInfo config) {
482e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        WpsResult result = new WpsResult();
483fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if (mWifiNative.startWpsPbc(config.BSSID)) {
4845ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff            /* WPS leaves all networks disabled */
4855ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff            markAllNetworksDisabled();
486e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            result.status = WpsResult.Status.SUCCESS;
487e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        } else {
4887f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Failed to start WPS push button configuration");
489e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff            result.status = WpsResult.Status.FAILURE;
4905ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff        }
491e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriff        return result;
4925ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
4935ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
4945ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    /**
49596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * Fetch the link properties for a given network id
496d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return LinkProperties for the given network id
49731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff     */
498fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    LinkProperties getLinkProperties(int netId) {
499fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        WifiConfiguration config = mConfiguredNetworks.get(netId);
500e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        if (config != null) return new LinkProperties(config.linkProperties);
50131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        return null;
50231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    }
50331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
50431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    /**
50596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * get IP configuration for a given network id
50696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * TODO: We cannot handle IPv6 addresses for configuration
50796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     *       right now until NetworkUtils is fixed. When we do
50896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     *       that, we should remove handling DhcpInfo and move
50996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     *       to using LinkProperties
510d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return DhcpInfoInternal for the given network id
51196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     */
512fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    DhcpInfoInternal getIpConfiguration(int netId) {
5130216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
51496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        LinkProperties linkProperties = getLinkProperties(netId);
51596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
51696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (linkProperties != null) {
51796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            Iterator<LinkAddress> iter = linkProperties.getLinkAddresses().iterator();
51896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            if (iter.hasNext()) {
5190216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                LinkAddress linkAddress = iter.next();
5200216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                dhcpInfoInternal.ipAddress = linkAddress.getAddress().getHostAddress();
521aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                for (RouteInfo route : linkProperties.getRoutes()) {
522aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                    dhcpInfoInternal.addRoute(route);
523992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                }
5240216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                dhcpInfoInternal.prefixLength = linkAddress.getNetworkPrefixLength();
5250216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                Iterator<InetAddress> dnsIterator = linkProperties.getDnses().iterator();
5260216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                dhcpInfoInternal.dns1 = dnsIterator.next().getHostAddress();
5270216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                if (dnsIterator.hasNext()) {
5280216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt                    dhcpInfoInternal.dns2 = dnsIterator.next().getHostAddress();
52996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                }
53096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            }
53196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        }
5320216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt        return dhcpInfoInternal;
53396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    }
53496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
53596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    /**
53684cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff     * set IP configuration for a given network id
53784cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff     */
538fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    void setIpConfiguration(int netId, DhcpInfoInternal dhcpInfo) {
53984cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff        LinkProperties linkProperties = dhcpInfo.makeLinkProperties();
54084cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff
541fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        WifiConfiguration config = mConfiguredNetworks.get(netId);
542e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        if (config != null) {
543e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            // add old proxy details
544e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            if(config.linkProperties != null) {
545e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                linkProperties.setHttpProxy(config.linkProperties.getHttpProxy());
54684cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff            }
547e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            config.linkProperties = linkProperties;
54884cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff        }
54984cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff    }
55084cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff
5510c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff    /**
5520c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff     * clear IP configuration for a given network id
553d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @param network id
5540c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff     */
555fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    void clearIpConfiguration(int netId) {
556fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        WifiConfiguration config = mConfiguredNetworks.get(netId);
557e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        if (config != null && config.linkProperties != null) {
558e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            // Clear everything except proxy
559e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            ProxyProperties proxy = config.linkProperties.getHttpProxy();
560e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            config.linkProperties.clear();
561e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            config.linkProperties.setHttpProxy(proxy);
5620c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff        }
5630c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff    }
5640c13d479398ab4d940a302d2efd37cfeee51f872Irfan Sheriff
56584cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff
56684cffa45261519a96949ec5c6cd8e21fea950ff5Irfan Sheriff    /**
567128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff     * Fetch the proxy properties for a given network id
568d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @param network id
569d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return ProxyProperties for the network id
570128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff     */
571fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    ProxyProperties getProxyProperties(int netId) {
57296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        LinkProperties linkProperties = getLinkProperties(netId);
57396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (linkProperties != null) {
57496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            return new ProxyProperties(linkProperties.getHttpProxy());
575128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        }
576128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        return null;
577128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff    }
578128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
579128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff    /**
58031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff     * Return if the specified network is using static IP
581d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @param network id
582d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     * @return {@code true} if using static ip for netId
58331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff     */
584fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    boolean isUsingStaticIp(int netId) {
585fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        WifiConfiguration config = mConfiguredNetworks.get(netId);
586e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        if (config != null && config.ipAssignment == IpAssignment.STATIC) {
587e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            return true;
58831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
58931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        return false;
59031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    }
59131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
5921b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood    /**
5931b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood     * Should be called when a single network configuration is made.
5941b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood     * @param network The network configuration that changed.
5951b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood     * @param reason The reason for the change, should be one of WifiManager.CHANGE_REASON_ADDED,
5961b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood     * WifiManager.CHANGE_REASON_REMOVED, or WifiManager.CHANGE_REASON_CHANGE.
5971b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood     */
5981b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood    private void sendConfiguredNetworksChangedBroadcast(WifiConfiguration network,
5991b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            int reason) {
6001b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        Intent intent = new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
6011b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
6021b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        intent.putExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, false);
6031b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        intent.putExtra(WifiManager.EXTRA_WIFI_CONFIGURATION, network);
6041b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        intent.putExtra(WifiManager.EXTRA_CHANGE_REASON, reason);
6055ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
6061b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood    }
6071b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood
6081b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood    /**
6091b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood     * Should be called when multiple network configuration changes are made.
6101b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood     */
611fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private void sendConfiguredNetworksChangedBroadcast() {
612be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        Intent intent = new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
613be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
6141b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        intent.putExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, true);
6155ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
61604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
61704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
618fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    void loadConfiguredNetworks() {
619fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        String listStr = mWifiNative.listNetworks();
620fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mLastPriority = 0;
62104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
622fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mConfiguredNetworks.clear();
623fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mNetworkIds.clear();
624e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
625e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        if (listStr == null)
626e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            return;
627e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
628e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        String[] lines = listStr.split("\n");
629e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        // Skip the first line, which is a header
630e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        for (int i = 1; i < lines.length; i++) {
631e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            String[] result = lines[i].split("\t");
632e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            // network-id | ssid | bssid | flags
633e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            WifiConfiguration config = new WifiConfiguration();
634e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            try {
635e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                config.networkId = Integer.parseInt(result[0]);
636e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            } catch(NumberFormatException e) {
637e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                continue;
638e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            }
639e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            if (result.length > 3) {
640e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                if (result[3].indexOf("[CURRENT]") != -1)
641e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    config.status = WifiConfiguration.Status.CURRENT;
642e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                else if (result[3].indexOf("[DISABLED]") != -1)
643e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    config.status = WifiConfiguration.Status.DISABLED;
644e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                else
64504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    config.status = WifiConfiguration.Status.ENABLED;
646e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            } else {
647e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                config.status = WifiConfiguration.Status.ENABLED;
64804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
649e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            readNetworkVariables(config);
650fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (config.priority > mLastPriority) {
651fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mLastPriority = config.priority;
652e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            }
653fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mConfiguredNetworks.put(config.networkId, config);
654fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mNetworkIds.put(configKey(config), config.networkId);
65504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
656e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
657128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        readIpAndProxyConfigurations();
658be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        sendConfiguredNetworksChangedBroadcast();
6595ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
6605ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
6615ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    /* Mark all networks except specified netId as disabled */
662fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private void markAllNetworksDisabledExcept(int netId) {
663fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        for(WifiConfiguration config : mConfiguredNetworks.values()) {
664e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            if(config != null && config.networkId != netId) {
665e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                if (config.status != Status.DISABLED) {
666e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    config.status = Status.DISABLED;
667e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    config.disableReason = WifiConfiguration.DISABLED_UNKNOWN_REASON;
6685ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff                }
6695ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff            }
6705ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff        }
6715ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff    }
6725ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff
673fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private void markAllNetworksDisabled() {
6745ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff        markAllNetworksDisabledExcept(INVALID_NETWORK_ID);
67531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    }
67631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
677fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private void writeIpAndProxyConfigurations() {
67831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
679e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        /* Make a copy */
680e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
681fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        for(WifiConfiguration config : mConfiguredNetworks.values()) {
682e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            networks.add(new WifiConfiguration(config));
683e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff        }
68431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
685fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        DelayedDiskWrite.write(networks);
686e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff    }
687e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
688fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private static class DelayedDiskWrite {
689e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
690fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private static HandlerThread sDiskWriteHandlerThread;
691fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private static Handler sDiskWriteHandler;
692fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        /* Tracks multiple writes on the same thread */
693fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private static int sWriteSequence = 0;
694fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private static final String TAG = "DelayedDiskWrite";
695e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
696fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        static void write (final List<WifiConfiguration> networks) {
697e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
698fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            /* Do a delayed write to disk on a seperate handler thread */
699fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            synchronized (DelayedDiskWrite.class) {
700fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                if (++sWriteSequence == 1) {
701fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    sDiskWriteHandlerThread = new HandlerThread("WifiConfigThread");
702fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    sDiskWriteHandlerThread.start();
703fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    sDiskWriteHandler = new Handler(sDiskWriteHandlerThread.getLooper());
704fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                }
705e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            }
706128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
707fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            sDiskWriteHandler.post(new Runnable() {
708fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    @Override
709fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    public void run() {
710fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        onWriteCalled(networks);
711fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    }
712fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                });
713fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        }
714fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff
715fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private static void onWriteCalled(List<WifiConfiguration> networks) {
716e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
717e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            DataOutputStream out = null;
718e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            try {
719e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                out = new DataOutputStream(new BufferedOutputStream(
720e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                            new FileOutputStream(ipConfigFile)));
721e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
722e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                out.writeInt(IPCONFIG_FILE_VERSION);
723e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
724e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                for(WifiConfiguration config : networks) {
725128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                    boolean writeToFile = false;
726128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
72796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                    try {
72896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        LinkProperties linkProperties = config.linkProperties;
72996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        switch (config.ipAssignment) {
73096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            case STATIC:
73196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(IP_ASSIGNMENT_KEY);
73296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(config.ipAssignment.toString());
73396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
73496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                    out.writeUTF(LINK_ADDRESS_KEY);
73596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                    out.writeUTF(linkAddr.getAddress().getHostAddress());
73696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                    out.writeInt(linkAddr.getNetworkPrefixLength());
737128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                                }
738aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                for (RouteInfo route : linkProperties.getRoutes()) {
73996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                    out.writeUTF(GATEWAY_KEY);
740aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                    LinkAddress dest = route.getDestination();
741aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                    if (dest != null) {
742aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                        out.writeInt(1);
743aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                        out.writeUTF(dest.getAddress().getHostAddress());
744aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                        out.writeInt(dest.getNetworkPrefixLength());
745aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                    } else {
746aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                        out.writeInt(0);
747aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                    }
748aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                    if (route.getGateway() != null) {
749aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                        out.writeInt(1);
750aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                        out.writeUTF(route.getGateway().getHostAddress());
751aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                    } else {
752aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                        out.writeInt(0);
753aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                    }
75496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                }
75596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                for (InetAddress inetAddr : linkProperties.getDnses()) {
75696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                    out.writeUTF(DNS_KEY);
75796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                    out.writeUTF(inetAddr.getHostAddress());
75896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                }
75996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                writeToFile = true;
76096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                break;
76196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            case DHCP:
76296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(IP_ASSIGNMENT_KEY);
76396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(config.ipAssignment.toString());
76496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                writeToFile = true;
76596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                break;
76696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            case UNASSIGNED:
76796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                /* Ignore */
76896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                break;
76996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            default:
7707f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                                loge("Ignore invalid ip assignment while writing");
77196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                break;
77296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        }
773128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
77496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        switch (config.proxySettings) {
77596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            case STATIC:
77696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                ProxyProperties proxyProperties = linkProperties.getHttpProxy();
77796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                String exclusionList = proxyProperties.getExclusionList();
77896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(PROXY_SETTINGS_KEY);
77996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(config.proxySettings.toString());
78096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(PROXY_HOST_KEY);
781434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                                out.writeUTF(proxyProperties.getHost());
78296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(PROXY_PORT_KEY);
783434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                                out.writeInt(proxyProperties.getPort());
78496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(EXCLUSION_LIST_KEY);
78596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(exclusionList);
78696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                writeToFile = true;
78796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                break;
78896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            case NONE:
78996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(PROXY_SETTINGS_KEY);
79096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                out.writeUTF(config.proxySettings.toString());
79196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                writeToFile = true;
79296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                break;
79396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            case UNASSIGNED:
79496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                /* Ignore */
79596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                break;
79696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            default:
797fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                                loge("Ignthisore invalid proxy settings while writing");
79896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                                break;
79996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        }
80096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        if (writeToFile) {
80196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            out.writeUTF(ID_KEY);
80296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            out.writeInt(configKey(config));
80396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        }
80496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                    } catch (NullPointerException e) {
8057f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Failure in writing " + config.linkProperties + e);
806128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                    }
80796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                    out.writeUTF(EOS);
80831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                }
80931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
810e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            } catch (IOException e) {
811e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                loge("Error writing data file");
812e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff            } finally {
813e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                if (out != null) {
814e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    try {
815e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                        out.close();
816e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    } catch (Exception e) {}
817e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                }
818e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff
819e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                //Quit if no more writes sent
820fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                synchronized (DelayedDiskWrite.class) {
821e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    if (--sWriteSequence == 0) {
822fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        sDiskWriteHandler.getLooper().quit();
823fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        sDiskWriteHandler = null;
824e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                        sDiskWriteHandlerThread = null;
825e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    }
826e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                }
82731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            }
828fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        }
829fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff
830fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private static void loge(String s) {
831fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            Log.e(TAG, s);
832fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        }
83331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    }
83431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
835fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private void readIpAndProxyConfigurations() {
83631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
837128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        DataInputStream in = null;
83831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        try {
839128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff            in = new DataInputStream(new BufferedInputStream(new FileInputStream(
840128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                    ipConfigFile)));
841128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
842aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            int version = in.readInt();
843aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            if (version != 2 && version != 1) {
8447f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Bad version on IP configuration file, ignore read");
84531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                return;
84631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            }
84731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
848128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff            while (true) {
849128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                int id = -1;
850128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                IpAssignment ipAssignment = IpAssignment.UNASSIGNED;
851128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                ProxySettings proxySettings = ProxySettings.UNASSIGNED;
85296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                LinkProperties linkProperties = new LinkProperties();
853128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                String proxyHost = null;
854128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                int proxyPort = -1;
855128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                String exclusionList = null;
856128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                String key;
857128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
858128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                do {
859128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                    key = in.readUTF();
86096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                    try {
86196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        if (key.equals(ID_KEY)) {
86296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            id = in.readInt();
86396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else if (key.equals(IP_ASSIGNMENT_KEY)) {
86496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            ipAssignment = IpAssignment.valueOf(in.readUTF());
86596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else if (key.equals(LINK_ADDRESS_KEY)) {
866e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt                            LinkAddress linkAddr = new LinkAddress(
867e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt                                    NetworkUtils.numericToInetAddress(in.readUTF()), in.readInt());
86896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            linkProperties.addLinkAddress(linkAddr);
86996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else if (key.equals(GATEWAY_KEY)) {
870aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                            LinkAddress dest = null;
871aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                            InetAddress gateway = null;
872aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                            if (version == 1) {
873aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                // only supported default gateways - leave the dest/prefix empty
874aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                gateway = NetworkUtils.numericToInetAddress(in.readUTF());
875aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                            } else {
876aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                if (in.readInt() == 1) {
877aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                    dest = new LinkAddress(
878aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                            NetworkUtils.numericToInetAddress(in.readUTF()),
879aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                            in.readInt());
880aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                }
881aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                if (in.readInt() == 1) {
882aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                    gateway = NetworkUtils.numericToInetAddress(in.readUTF());
883aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                                }
884aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                            }
885aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                            linkProperties.addRoute(new RouteInfo(dest, gateway));
88696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else if (key.equals(DNS_KEY)) {
887e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt                            linkProperties.addDns(
888e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt                                    NetworkUtils.numericToInetAddress(in.readUTF()));
88996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else if (key.equals(PROXY_SETTINGS_KEY)) {
89096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            proxySettings = ProxySettings.valueOf(in.readUTF());
89196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else if (key.equals(PROXY_HOST_KEY)) {
89296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            proxyHost = in.readUTF();
89396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else if (key.equals(PROXY_PORT_KEY)) {
89496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            proxyPort = in.readInt();
89596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else if (key.equals(EXCLUSION_LIST_KEY)) {
89696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            exclusionList = in.readUTF();
89796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else if (key.equals(EOS)) {
89896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                            break;
89996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        } else {
9007f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                            loge("Ignore unknown key " + key + "while reading");
90196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        }
902e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt                    } catch (IllegalArgumentException e) {
9037f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge("Ignore invalid address while reading" + e);
90431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    }
905128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                } while (true);
90631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
907128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                if (id != -1) {
908fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    WifiConfiguration config = mConfiguredNetworks.get(
909fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                            mNetworkIds.get(id));
91031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
911e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    if (config == null) {
912e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                        loge("configuration found for missing network, ignored");
913e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                    } else {
914e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                        config.linkProperties = linkProperties;
915e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                        switch (ipAssignment) {
916e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                            case STATIC:
917e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                            case DHCP:
918e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                config.ipAssignment = ipAssignment;
919e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                break;
920e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                            case UNASSIGNED:
921e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                //Ignore
922e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                break;
923e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                            default:
924e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                loge("Ignore invalid ip assignment while reading");
925e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                break;
926e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                        }
927128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
928e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                        switch (proxySettings) {
929e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                            case STATIC:
930e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                config.proxySettings = proxySettings;
931e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                ProxyProperties proxyProperties =
932e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                    new ProxyProperties(proxyHost, proxyPort, exclusionList);
933e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                linkProperties.setHttpProxy(proxyProperties);
934e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                break;
935e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                            case NONE:
936e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                config.proxySettings = proxySettings;
937e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                break;
938e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                            case UNASSIGNED:
939e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                //Ignore
940e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                break;
941e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                            default:
942e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                loge("Ignore invalid proxy settings while reading");
943e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff                                break;
94431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                        }
94531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                    }
94631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                } else {
94786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    if (DBG) log("Missing id while parsing configuration");
94831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                }
94931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            }
95096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        } catch (EOFException ignore) {
951128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        } catch (IOException e) {
9527f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            loge("Error parsing configuration" + e);
953128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        } finally {
954128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff            if (in != null) {
955128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                try {
956128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                    in.close();
957128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff                } catch (Exception e) {}
958128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff            }
95931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
96004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
96104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
962fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private NetworkUpdateResult addOrUpdateNetworkNative(WifiConfiguration config) {
96304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        /*
9645ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff         * If the supplied networkId is INVALID_NETWORK_ID, we create a new empty
96504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff         * network configuration. Otherwise, the networkId should
96604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff         * refer to an existing configuration.
96704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff         */
96804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        int netId = config.networkId;
9698fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy        boolean newNetwork = false;
9705ee89800bee7c6c755778795a536e0e2f12b85ffIrfan Sheriff        // networkId of INVALID_NETWORK_ID means we want to create a new network
9718fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy        if (netId == INVALID_NETWORK_ID) {
972fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            Integer savedNetId = mNetworkIds.get(configKey(config));
9738fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy            if (savedNetId != null) {
9748fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy                netId = savedNetId;
9758fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy            } else {
9768fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy                newNetwork = true;
977fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                netId = mWifiNative.addNetwork();
9788fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy                if (netId < 0) {
9797f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("Failed to add a network!");
9808fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy                    return new NetworkUpdateResult(INVALID_NETWORK_ID);
9818fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy                }
9828fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy            }
98304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
98404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
9858fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy        boolean updateFailed = true;
9868fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy
98704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        setVariables: {
98804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
98904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (config.SSID != null &&
990fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    !mWifiNative.setNetworkVariable(
99104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
99204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.ssidVarName,
99304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        config.SSID)) {
9947f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("failed to set SSID: "+config.SSID);
99504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
99604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
99704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
99804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (config.BSSID != null &&
999fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    !mWifiNative.setNetworkVariable(
100004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
100104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.bssidVarName,
100204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        config.BSSID)) {
10037f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("failed to set BSSID: "+config.BSSID);
100404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
100504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
100604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
100704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String allowedKeyManagementString =
100804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                makeString(config.allowedKeyManagement, WifiConfiguration.KeyMgmt.strings);
100904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (config.allowedKeyManagement.cardinality() != 0 &&
1010fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    !mWifiNative.setNetworkVariable(
101104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
101204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.KeyMgmt.varName,
101304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedKeyManagementString)) {
10147f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("failed to set key_mgmt: "+
101504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedKeyManagementString);
101604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
101704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
101804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
101904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String allowedProtocolsString =
102004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                makeString(config.allowedProtocols, WifiConfiguration.Protocol.strings);
102104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (config.allowedProtocols.cardinality() != 0 &&
1022fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    !mWifiNative.setNetworkVariable(
102304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
102404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.Protocol.varName,
102504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedProtocolsString)) {
10267f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("failed to set proto: "+
102704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedProtocolsString);
102804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
102904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
103004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
103104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String allowedAuthAlgorithmsString =
103204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                makeString(config.allowedAuthAlgorithms, WifiConfiguration.AuthAlgorithm.strings);
103304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (config.allowedAuthAlgorithms.cardinality() != 0 &&
1034fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    !mWifiNative.setNetworkVariable(
103504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
103604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.AuthAlgorithm.varName,
103704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedAuthAlgorithmsString)) {
10387f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("failed to set auth_alg: "+
103904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedAuthAlgorithmsString);
104004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
104104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
104204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
104304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String allowedPairwiseCiphersString =
104404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    makeString(config.allowedPairwiseCiphers,
104504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfiguration.PairwiseCipher.strings);
104604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (config.allowedPairwiseCiphers.cardinality() != 0 &&
1047fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    !mWifiNative.setNetworkVariable(
104804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
104904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.PairwiseCipher.varName,
105004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedPairwiseCiphersString)) {
10517f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("failed to set pairwise: "+
105204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedPairwiseCiphersString);
105304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
105404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
105504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
105604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String allowedGroupCiphersString =
105704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                makeString(config.allowedGroupCiphers, WifiConfiguration.GroupCipher.strings);
105804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (config.allowedGroupCiphers.cardinality() != 0 &&
1059fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    !mWifiNative.setNetworkVariable(
106004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
106104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.GroupCipher.varName,
106204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedGroupCiphersString)) {
10637f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("failed to set group: "+
106404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        allowedGroupCiphersString);
106504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
106604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
106704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
106804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            // Prevent client screw-up by passing in a WifiConfiguration we gave it
106904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            // by preventing "*" as a key.
107004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (config.preSharedKey != null && !config.preSharedKey.equals("*") &&
1071fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    !mWifiNative.setNetworkVariable(
107204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
107304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.pskVarName,
107404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        config.preSharedKey)) {
10757f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("failed to set psk");
107604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
107704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
107804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
107904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            boolean hasSetKey = false;
108004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (config.wepKeys != null) {
108104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                for (int i = 0; i < config.wepKeys.length; i++) {
108204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    // Prevent client screw-up by passing in a WifiConfiguration we gave it
108304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    // by preventing "*" as a key.
108404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    if (config.wepKeys[i] != null && !config.wepKeys[i].equals("*")) {
1085fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        if (!mWifiNative.setNetworkVariable(
108604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                                    netId,
108704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                                    WifiConfiguration.wepKeyVarNames[i],
108804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                                    config.wepKeys[i])) {
10897f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                            loge("failed to set wep_key" + i + ": " + config.wepKeys[i]);
109004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                            break setVariables;
109104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        }
109204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        hasSetKey = true;
109304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    }
109404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                }
109504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
109604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
109704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (hasSetKey) {
1098fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                if (!mWifiNative.setNetworkVariable(
109904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                            netId,
110004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                            WifiConfiguration.wepTxKeyIdxVarName,
110104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                            Integer.toString(config.wepTxKeyIndex))) {
11027f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                    loge("failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
110304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    break setVariables;
110404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                }
110504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
110604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1107fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (!mWifiNative.setNetworkVariable(
110804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
110904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.priorityVarName,
111004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        Integer.toString(config.priority))) {
11117f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge(config.SSID + ": failed to set priority: "
111204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        +config.priority);
111304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
111404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
111504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1116fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            if (config.hiddenSSID && !mWifiNative.setNetworkVariable(
111704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        netId,
111804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        WifiConfiguration.hiddenSSIDVarName,
111904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        Integer.toString(config.hiddenSSID ? 1 : 0))) {
11207f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge(config.SSID + ": failed to set hiddenSSID: "+
112104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        config.hiddenSSID);
112204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                break setVariables;
112304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
112404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
112504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            for (WifiConfiguration.EnterpriseField field
112604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    : config.enterpriseFields) {
112704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                String varName = field.varName();
112804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                String value = field.value();
112904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                if (value != null) {
11304e62fd3f95ee824e6addf438f9e1155a8e0b8e2aKenny Root                    if (field == config.engine) {
11314e62fd3f95ee824e6addf438f9e1155a8e0b8e2aKenny Root                        /*
11324e62fd3f95ee824e6addf438f9e1155a8e0b8e2aKenny Root                         * If the field is declared as an integer, it must not
11334e62fd3f95ee824e6addf438f9e1155a8e0b8e2aKenny Root                         * be null
11344e62fd3f95ee824e6addf438f9e1155a8e0b8e2aKenny Root                         */
11354e62fd3f95ee824e6addf438f9e1155a8e0b8e2aKenny Root                        if (value.length() == 0) {
11364e62fd3f95ee824e6addf438f9e1155a8e0b8e2aKenny Root                            value = "0";
11374e62fd3f95ee824e6addf438f9e1155a8e0b8e2aKenny Root                        }
11384e62fd3f95ee824e6addf438f9e1155a8e0b8e2aKenny Root                    } else if (field != config.eap) {
113904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        value = (value.length() == 0) ? "NULL" : convertToQuotedString(value);
114004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    }
1141fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (!mWifiNative.setNetworkVariable(
114204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                                netId,
114304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                                varName,
114404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                                value)) {
11457f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                        loge(config.SSID + ": failed to set " + varName +
114604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                                ": " + value);
114704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                        break setVariables;
114804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    }
114904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                }
115004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
115131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            updateFailed = false;
115204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
115304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
115431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        if (updateFailed) {
115531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            if (newNetwork) {
1156fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                mWifiNative.removeNetwork(netId);
11577f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Failed to set a network variable, removed network: " + netId);
115831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            }
1159be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff            return new NetworkUpdateResult(INVALID_NETWORK_ID);
116004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
116104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
116231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        /* An update of the network variables requires reading them
1163fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff         * back from the supplicant to update mConfiguredNetworks.
116431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff         * This is because some of the variables (SSID, wep keys &
116531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff         * passphrases) reflect different values when read back than
116631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff         * when written. For example, wep key is stored as * irrespective
116731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff         * of the value sent to the supplicant
116831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff         */
1169fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        WifiConfiguration currentConfig = mConfiguredNetworks.get(netId);
1170fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        if (currentConfig == null) {
1171fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            currentConfig = new WifiConfiguration();
1172fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            currentConfig.networkId = netId;
117331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
11748fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy
1175fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        readNetworkVariables(currentConfig);
1176be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff
1177fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mConfiguredNetworks.put(netId, currentConfig);
1178fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mNetworkIds.put(configKey(currentConfig), netId);
11798fd4a3d0f72b3175936f1dd9ca174a91d196971fIsaac Levy
1180fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        NetworkUpdateResult result = writeIpAndProxyConfigurationsOnChange(currentConfig, config);
11811b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood        result.setIsNewNetwork(newNetwork);
1182be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        result.setNetworkId(netId);
1183be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return result;
1184128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff    }
118531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
1186128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff    /* Compare current and new configuration and write to file on change */
1187fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private NetworkUpdateResult writeIpAndProxyConfigurationsOnChange(
1188be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff            WifiConfiguration currentConfig,
1189128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff            WifiConfiguration newConfig) {
119096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        boolean ipChanged = false;
119196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        boolean proxyChanged = false;
119296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        LinkProperties linkProperties = new LinkProperties();
119396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
119496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        switch (newConfig.ipAssignment) {
119596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            case STATIC:
119696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                Collection<LinkAddress> currentLinkAddresses = currentConfig.linkProperties
119796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        .getLinkAddresses();
119896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                Collection<LinkAddress> newLinkAddresses = newConfig.linkProperties
119996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        .getLinkAddresses();
120096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                Collection<InetAddress> currentDnses = currentConfig.linkProperties.getDnses();
120196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                Collection<InetAddress> newDnses = newConfig.linkProperties.getDnses();
1202aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                Collection<RouteInfo> currentRoutes = currentConfig.linkProperties.getRoutes();
1203aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                Collection<RouteInfo> newRoutes = newConfig.linkProperties.getRoutes();
1204992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt
1205992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                boolean linkAddressesDiffer =
1206992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                        (currentLinkAddresses.size() != newLinkAddresses.size()) ||
1207992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                        !currentLinkAddresses.containsAll(newLinkAddresses);
1208992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                boolean dnsesDiffer = (currentDnses.size() != newDnses.size()) ||
1209992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                        !currentDnses.containsAll(newDnses);
1210aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                boolean routesDiffer = (currentRoutes.size() != newRoutes.size()) ||
1211aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                        !currentRoutes.containsAll(newRoutes);
121296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
121396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                if ((currentConfig.ipAssignment != newConfig.ipAssignment) ||
121496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        linkAddressesDiffer ||
121596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                        dnsesDiffer ||
1216aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                        routesDiffer) {
121796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                    ipChanged = true;
121896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                }
121996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                break;
122096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            case DHCP:
122196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                if (currentConfig.ipAssignment != newConfig.ipAssignment) {
122296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                    ipChanged = true;
122396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                }
122496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                break;
122596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            case UNASSIGNED:
122696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                /* Ignore */
122796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                break;
122896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            default:
12297f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Ignore invalid ip assignment during write");
123096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                break;
123131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
1232128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
123396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        switch (newConfig.proxySettings) {
123496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            case STATIC:
123596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                ProxyProperties newHttpProxy = newConfig.linkProperties.getHttpProxy();
123696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                ProxyProperties currentHttpProxy = currentConfig.linkProperties.getHttpProxy();
1237128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
1238434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                if (newHttpProxy != null) {
1239434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    proxyChanged = !newHttpProxy.equals(currentHttpProxy);
1240434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                } else {
1241434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    proxyChanged = (currentHttpProxy != null);
124296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                }
124396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                break;
124496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            case NONE:
124596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                if (currentConfig.proxySettings != newConfig.proxySettings) {
124696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                    proxyChanged = true;
124796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                }
124896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                break;
124996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            case UNASSIGNED:
125096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                /* Ignore */
125196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                break;
125296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            default:
12537f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                loge("Ignore invalid proxy configuration during write");
125496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                break;
125596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        }
1256128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
125796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (!ipChanged) {
125896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            addIpSettingsFromConfig(linkProperties, currentConfig);
125996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        } else {
126096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            currentConfig.ipAssignment = newConfig.ipAssignment;
126196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            addIpSettingsFromConfig(linkProperties, newConfig);
12627f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            log("IP config changed SSID = " + currentConfig.SSID + " linkProperties: " +
126396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                    linkProperties.toString());
126496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        }
126596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
126696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
126796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (!proxyChanged) {
126896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            linkProperties.setHttpProxy(currentConfig.linkProperties.getHttpProxy());
126996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        } else {
127096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            currentConfig.proxySettings = newConfig.proxySettings;
127196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            linkProperties.setHttpProxy(newConfig.linkProperties.getHttpProxy());
12727f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff            log("proxy changed SSID = " + currentConfig.SSID);
127396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            if (linkProperties.getHttpProxy() != null) {
12747f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff                log(" proxyProperties: " + linkProperties.getHttpProxy().toString());
1275128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff            }
1276128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        }
1277128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff
127896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (ipChanged || proxyChanged) {
127996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            currentConfig.linkProperties = linkProperties;
1280128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff            writeIpAndProxyConfigurations();
12811b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood            sendConfiguredNetworksChangedBroadcast(currentConfig,
12821b6989cdc212aec7579489a362f99b791abe7352Mike Lockwood                    WifiManager.CHANGE_REASON_CONFIG_CHANGE);
1283128cecab968337038591cc14e3cdd5b37b2e5cb9Irfan Sheriff        }
1284be9ee6a498afc08df1ca6d796b703b703b25c9a9Irfan Sheriff        return new NetworkUpdateResult(ipChanged, proxyChanged);
128504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
128604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1287fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private void addIpSettingsFromConfig(LinkProperties linkProperties,
128896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            WifiConfiguration config) {
128996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        for (LinkAddress linkAddr : config.linkProperties.getLinkAddresses()) {
129096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            linkProperties.addLinkAddress(linkAddr);
129196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        }
1292aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        for (RouteInfo route : config.linkProperties.getRoutes()) {
1293aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            linkProperties.addRoute(route);
1294992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt        }
129596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        for (InetAddress dns : config.linkProperties.getDnses()) {
129696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            linkProperties.addDns(dns);
129796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        }
129896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    }
129996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
130004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    /**
130104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * Read the variables from the supplicant daemon that are needed to
130204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * fill in the WifiConfiguration object.
130304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     *
130404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     * @param config the {@link WifiConfiguration} object to be filled in.
130504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff     */
1306fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private void readNetworkVariables(WifiConfiguration config) {
130704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
130804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        int netId = config.networkId;
130904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (netId < 0)
131004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            return;
131104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
131204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        /*
131304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff         * TODO: maybe should have a native method that takes an array of
131404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff         * variable names and returns an array of values. But we'd still
131504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff         * be doing a round trip to the supplicant daemon for each variable.
131604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff         */
131704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        String value;
131804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1319fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.ssidVarName);
132004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
1321b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            if (value.charAt(0) != '"') {
1322b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                config.SSID = "\"" + WifiSsid.createFromHex(value).toString() + "\"";
1323b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                //TODO: convert a hex string that is not UTF-8 decodable to a P-formatted
1324b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                //supplicant string
1325b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            } else {
1326b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                config.SSID = value;
1327b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            }
132804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        } else {
132904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            config.SSID = null;
133004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
133104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1332fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.bssidVarName);
133304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
133404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            config.BSSID = value;
133504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        } else {
133604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            config.BSSID = null;
133704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
133804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1339fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.priorityVarName);
134004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        config.priority = -1;
134104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
134204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            try {
134304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                config.priority = Integer.parseInt(value);
134404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            } catch (NumberFormatException ignore) {
134504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
134604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
134704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1348fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.hiddenSSIDVarName);
134904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        config.hiddenSSID = false;
135004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
135104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            try {
135204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                config.hiddenSSID = Integer.parseInt(value) != 0;
135304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            } catch (NumberFormatException ignore) {
135404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
135504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
135604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1357fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.wepTxKeyIdxVarName);
135804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        config.wepTxKeyIndex = -1;
135904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
136004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            try {
136104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                config.wepTxKeyIndex = Integer.parseInt(value);
136204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            } catch (NumberFormatException ignore) {
136304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
136404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
136504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
136604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        for (int i = 0; i < 4; i++) {
1367fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            value = mWifiNative.getNetworkVariable(netId,
136804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    WifiConfiguration.wepKeyVarNames[i]);
136904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (!TextUtils.isEmpty(value)) {
137004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                config.wepKeys[i] = value;
137104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            } else {
137204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                config.wepKeys[i] = null;
137304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
137404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
137504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1376fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.pskVarName);
137704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
137804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            config.preSharedKey = value;
137904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        } else {
138004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            config.preSharedKey = null;
138104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
138204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1383fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(config.networkId,
138404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                WifiConfiguration.Protocol.varName);
138504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
138604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String vals[] = value.split(" ");
138704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            for (String val : vals) {
138804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                int index =
138904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    lookupString(val, WifiConfiguration.Protocol.strings);
139004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                if (0 <= index) {
139104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    config.allowedProtocols.set(index);
139204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                }
139304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
139404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
139504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1396fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(config.networkId,
139704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                WifiConfiguration.KeyMgmt.varName);
139804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
139904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String vals[] = value.split(" ");
140004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            for (String val : vals) {
140104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                int index =
140204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    lookupString(val, WifiConfiguration.KeyMgmt.strings);
140304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                if (0 <= index) {
140404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    config.allowedKeyManagement.set(index);
140504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                }
140604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
140704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
140804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1409fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(config.networkId,
141004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                WifiConfiguration.AuthAlgorithm.varName);
141104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
141204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String vals[] = value.split(" ");
141304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            for (String val : vals) {
141404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                int index =
141504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    lookupString(val, WifiConfiguration.AuthAlgorithm.strings);
141604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                if (0 <= index) {
141704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    config.allowedAuthAlgorithms.set(index);
141804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                }
141904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
142004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
142104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1422fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(config.networkId,
142304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                WifiConfiguration.PairwiseCipher.varName);
142404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
142504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String vals[] = value.split(" ");
142604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            for (String val : vals) {
142704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                int index =
142804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    lookupString(val, WifiConfiguration.PairwiseCipher.strings);
142904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                if (0 <= index) {
143004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    config.allowedPairwiseCiphers.set(index);
143104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                }
143204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
143304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
143404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1435fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        value = mWifiNative.getNetworkVariable(config.networkId,
143604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                WifiConfiguration.GroupCipher.varName);
143704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (!TextUtils.isEmpty(value)) {
143804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            String vals[] = value.split(" ");
143904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            for (String val : vals) {
144004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                int index =
144104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    lookupString(val, WifiConfiguration.GroupCipher.strings);
144204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                if (0 <= index) {
144304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    config.allowedGroupCiphers.set(index);
144404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                }
144504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
144604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
144704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
144804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        for (WifiConfiguration.EnterpriseField field :
144904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                config.enterpriseFields) {
1450fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            value = mWifiNative.getNetworkVariable(netId,
145104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                    field.varName());
145204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (!TextUtils.isEmpty(value)) {
1453565f9f216aa87f11d451ae6532d5153001a386bfKenny Root                if (field != config.eap && field != config.engine) {
1454565f9f216aa87f11d451ae6532d5153001a386bfKenny Root                    value = removeDoubleQuotes(value);
1455565f9f216aa87f11d451ae6532d5153001a386bfKenny Root                }
145604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                field.setValue(value);
145704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            }
145804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
1459565f9f216aa87f11d451ae6532d5153001a386bfKenny Root
1460565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        migrateOldEapTlsIfNecessary(config, netId);
1461565f9f216aa87f11d451ae6532d5153001a386bfKenny Root    }
1462565f9f216aa87f11d451ae6532d5153001a386bfKenny Root
1463565f9f216aa87f11d451ae6532d5153001a386bfKenny Root    /**
1464565f9f216aa87f11d451ae6532d5153001a386bfKenny Root     * Migration code for old EAP-TLS configurations. This should only be used
1465565f9f216aa87f11d451ae6532d5153001a386bfKenny Root     * when restoring an old wpa_supplicant.conf or upgrading from a previous
1466565f9f216aa87f11d451ae6532d5153001a386bfKenny Root     * platform version.
1467565f9f216aa87f11d451ae6532d5153001a386bfKenny Root     *
1468565f9f216aa87f11d451ae6532d5153001a386bfKenny Root     * @param config the configuration to be migrated
1469565f9f216aa87f11d451ae6532d5153001a386bfKenny Root     * @param netId the wpa_supplicant's net ID
1470565f9f216aa87f11d451ae6532d5153001a386bfKenny Root     * @param value the old private_key value
1471565f9f216aa87f11d451ae6532d5153001a386bfKenny Root     */
1472565f9f216aa87f11d451ae6532d5153001a386bfKenny Root    private void migrateOldEapTlsIfNecessary(WifiConfiguration config, int netId) {
1473565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        String value = mWifiNative.getNetworkVariable(netId,
1474565f9f216aa87f11d451ae6532d5153001a386bfKenny Root                WifiConfiguration.OLD_PRIVATE_KEY_NAME);
1475565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        /*
1476565f9f216aa87f11d451ae6532d5153001a386bfKenny Root         * If the old configuration value is not present, then there is nothing
1477565f9f216aa87f11d451ae6532d5153001a386bfKenny Root         * to do.
1478565f9f216aa87f11d451ae6532d5153001a386bfKenny Root         */
1479565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        if (TextUtils.isEmpty(value)) {
1480565f9f216aa87f11d451ae6532d5153001a386bfKenny Root            return;
1481565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        } else {
1482565f9f216aa87f11d451ae6532d5153001a386bfKenny Root            // Also ignore it if it's empty quotes.
1483565f9f216aa87f11d451ae6532d5153001a386bfKenny Root            value = removeDoubleQuotes(value);
1484565f9f216aa87f11d451ae6532d5153001a386bfKenny Root            if (TextUtils.isEmpty(value)) {
1485565f9f216aa87f11d451ae6532d5153001a386bfKenny Root                return;
1486565f9f216aa87f11d451ae6532d5153001a386bfKenny Root            }
1487565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        }
1488565f9f216aa87f11d451ae6532d5153001a386bfKenny Root
1489565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        config.engine.setValue(WifiConfiguration.ENGINE_ENABLE);
1490565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        config.engine_id.setValue(convertToQuotedString(WifiConfiguration.KEYSTORE_ENGINE_ID));
1491565f9f216aa87f11d451ae6532d5153001a386bfKenny Root
1492565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        /*
1493565f9f216aa87f11d451ae6532d5153001a386bfKenny Root         * The old key started with the keystore:// URI prefix, but we don't
1494565f9f216aa87f11d451ae6532d5153001a386bfKenny Root         * need that anymore. Trim it off if it exists.
1495565f9f216aa87f11d451ae6532d5153001a386bfKenny Root         */
1496565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        final String keyName;
1497565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        if (value.startsWith(WifiConfiguration.KEYSTORE_URI)) {
1498565f9f216aa87f11d451ae6532d5153001a386bfKenny Root            keyName = new String(value.substring(WifiConfiguration.KEYSTORE_URI.length()));
1499565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        } else {
1500565f9f216aa87f11d451ae6532d5153001a386bfKenny Root            keyName = value;
1501565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        }
1502565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        config.key_id.setValue(convertToQuotedString(keyName));
1503565f9f216aa87f11d451ae6532d5153001a386bfKenny Root
1504565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        // Now tell the wpa_supplicant the new configuration values.
1505565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        final EnterpriseField needsUpdate[] = { config.engine, config.engine_id, config.key_id };
1506565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        for (EnterpriseField field : needsUpdate) {
1507565f9f216aa87f11d451ae6532d5153001a386bfKenny Root            mWifiNative.setNetworkVariable(netId, field.varName(), field.value());
1508565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        }
1509565f9f216aa87f11d451ae6532d5153001a386bfKenny Root
1510565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        // Remove old private_key string so we don't run this again.
1511565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        mWifiNative.setNetworkVariable(netId, WifiConfiguration.OLD_PRIVATE_KEY_NAME,
1512565f9f216aa87f11d451ae6532d5153001a386bfKenny Root                convertToQuotedString(""));
1513565f9f216aa87f11d451ae6532d5153001a386bfKenny Root
1514565f9f216aa87f11d451ae6532d5153001a386bfKenny Root        saveConfig();
151504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
151604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1517fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private String removeDoubleQuotes(String string) {
151804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (string.length() <= 2) return "";
151904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return string.substring(1, string.length() - 1);
152004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
152104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1522fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private String convertToQuotedString(String string) {
152304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return "\"" + string + "\"";
152404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
152504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1526fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private String makeString(BitSet set, String[] strings) {
152704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        StringBuffer buf = new StringBuffer();
152804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        int nextSetBit = -1;
152904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
153004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        /* Make sure all set bits are in [0, strings.length) to avoid
153104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff         * going out of bounds on strings.  (Shouldn't happen, but...) */
153204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        set = set.get(0, strings.length);
153304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
153404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
153504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            buf.append(strings[nextSetBit].replace('_', '-')).append(' ');
153604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
153704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
153804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        // remove trailing space
153904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        if (set.cardinality() > 0) {
154004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            buf.setLength(buf.length() - 1);
154104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
154204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
154304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return buf.toString();
154404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
154504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
1546fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private int lookupString(String string, String[] strings) {
154704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        int size = strings.length;
154804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
154904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        string = string.replace('-', '_');
155004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
155104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        for (int i = 0; i < size; i++)
155204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            if (string.equals(strings[i]))
155304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff                return i;
155404db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
155504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        // if we ever get here, we should probably add the
155604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        // value to WifiConfiguration to reflect that it's
155704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        // supported by the WPA supplicant
15587f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        loge("Failed to look-up a string: " + string);
155904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
156004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return -1;
156104db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
156204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff
156331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    /* Returns a unique for a given configuration */
156431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    private static int configKey(WifiConfiguration config) {
156531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        String key;
156631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
156731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
156831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            key = config.SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK];
156931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        } else if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
157031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff                config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
157131b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            key = config.SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
157231b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        } else if (config.wepKeys[0] != null) {
157331b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            key = config.SSID + "WEP";
157431b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        } else {
157531b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff            key = config.SSID + KeyMgmt.strings[KeyMgmt.NONE];
157631b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        }
157731b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
157831b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff        return key.hashCode();
157931b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff    }
158031b62322bfa9470d648fbfd69510e03da29b29afIrfan Sheriff
1581fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    String dump() {
158204db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        StringBuffer sb = new StringBuffer();
158304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        String LS = System.getProperty("line.separator");
1584fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        sb.append("mLastPriority ").append(mLastPriority).append(LS);
158504db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        sb.append("Configured networks ").append(LS);
158604db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        for (WifiConfiguration conf : getConfiguredNetworks()) {
158704db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff            sb.append(conf).append(LS);
158804db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        }
158904db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff        return sb.toString();
159004db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff    }
15914aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff
1592fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public String getConfigFile() {
15934aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff        return ipConfigFile;
15944aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff    }
15957f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff
1596fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private void loge(String s) {
15977f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        Log.e(TAG, s);
15987f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    }
15997f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff
1600fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private void log(String s) {
16017f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff        Log.d(TAG, s);
16027f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff    }
160304db1d5d3a51f9b710b707cfdc1c2f41ad948237Irfan Sheriff}
1604