/* * Copyright (C) 2010 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.zxing.client.android.wifi; import java.util.List; import java.util.regex.Pattern; import org.oskardroid.pg.R; import android.app.Activity; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import com.google.zxing.client.android.Intents; /** * A new activity showing the progress of Wifi connection * * @author Vikram Aggarwal */ public final class WifiActivity extends Activity { private static final String TAG = WifiActivity.class.getSimpleName(); private static final int MAX_ERROR_COUNT = 3; private static final int FAILURE_NO_NETWORK_ID = -1; private static final Pattern HEX_DIGITS_64 = Pattern.compile("[0-9A-Fa-f]{64}"); private WifiManager wifiManager; private TextView statusView; private WifiReceiver wifiReceiver; private boolean receiverRegistered; private int networkId; private int errorCount; private IntentFilter mWifiStateFilter; void gotError() { errorCount++; Log.d(TAG, "Encountered another error. Errorcount = " + errorCount); if (errorCount > MAX_ERROR_COUNT){ errorCount = 0; doError(R.string.wifi_connect_failed); } } public enum NetworkType { NETWORK_WEP, NETWORK_WPA, NETWORK_NOPASS, NETWORK_INVALID, } private int changeNetwork(NetworkSetting setting) { // If the SSID is empty, throw an error and return if (setting.getSsid() == null || setting.getSsid().length() == 0) { return doError(R.string.wifi_ssid_missing); } // If the network type is invalid if (setting.getNetworkType() == NetworkType.NETWORK_INVALID){ return doError(R.string.wifi_type_incorrect); } // If the password is empty, this is an unencrypted network if (setting.getPassword() == null || setting.getPassword().length() == 0 || setting.getNetworkType() == null || setting.getNetworkType() == NetworkType.NETWORK_NOPASS) { return changeNetworkUnEncrypted(setting); } if (setting.getNetworkType() == NetworkType.NETWORK_WPA) { return changeNetworkWPA(setting); } else { return changeNetworkWEP(setting); } } private int doError(int resource_string) { statusView.setText(resource_string); // Give up on the connection wifiManager.disconnect(); if (networkId > 0) { wifiManager.removeNetwork(networkId); networkId = -1; } if (receiverRegistered) { unregisterReceiver(wifiReceiver); receiverRegistered = false; } return -1; } private WifiConfiguration changeNetworkCommon(NetworkSetting input){ statusView.setText(R.string.wifi_creating_network); Log.d(TAG, "Adding new configuration: \nSSID: " + input.getSsid() + "\nType: " + input.getNetworkType()); WifiConfiguration config = new WifiConfiguration(); config.allowedAuthAlgorithms.clear(); config.allowedGroupCiphers.clear(); config.allowedKeyManagement.clear(); config.allowedPairwiseCiphers.clear(); config.allowedProtocols.clear(); // Android API insists that an ascii SSID must be quoted to be correctly handled. config.SSID = NetworkUtil.convertToQuotedString(input.getSsid()); config.hiddenSSID = true; return config; } private int requestNetworkChange(WifiConfiguration config){ statusView.setText(R.string.wifi_changing_network); return updateNetwork(config, false); } // Adding a WEP network private int changeNetworkWEP(NetworkSetting input) { WifiConfiguration config = changeNetworkCommon(input); String pass = input.getPassword(); if (NetworkUtil.isHexWepKey(pass)) { config.wepKeys[0] = pass; } else { config.wepKeys[0] = NetworkUtil.convertToQuotedString(pass); } config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104); config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); config.wepTxKeyIndex = 0; return requestNetworkChange(config); } // Adding a WPA or WPA2 network private int changeNetworkWPA(NetworkSetting input) { WifiConfiguration config = changeNetworkCommon(input); String pass = input.getPassword(); // Hex passwords that are 64 bits long are not to be quoted. if (HEX_DIGITS_64.matcher(pass).matches()){ Log.d(TAG, "A 64 bit hex password entered."); config.preSharedKey = pass; } else { Log.d(TAG, "A normal password entered: I am quoting it."); config.preSharedKey = NetworkUtil.convertToQuotedString(pass); } config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); // For WPA config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA2 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); return requestNetworkChange(config); } // Adding an open, unsecured network private int changeNetworkUnEncrypted(NetworkSetting input){ Log.d(TAG, "Empty password prompting a simple account setting"); WifiConfiguration config = changeNetworkCommon(input); config.wepKeys[0] = ""; config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); config.wepTxKeyIndex = 0; return requestNetworkChange(config); } /** * If the given ssid name exists in the settings, then change its password to the one given here, * and save * @param ssid */ private WifiConfiguration findNetworkInExistingConfig(String ssid){ List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks(); for (WifiConfiguration existingConfig : existingConfigs) { if (existingConfig.SSID.equals(ssid)) { return existingConfig; } } return null; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); if (intent == null || !intent.getAction().equals(Intents.WifiConnect.ACTION)) { finish(); return; } String ssid = intent.getStringExtra(Intents.WifiConnect.SSID); String password = intent.getStringExtra(Intents.WifiConnect.PASSWORD); String networkType = intent.getStringExtra(Intents.WifiConnect.TYPE); setContentView(R.layout.network); statusView = (TextView) findViewById(R.id.networkStatus); NetworkType networkT; if ("WPA".equals(networkType)) { networkT = NetworkType.NETWORK_WPA; } else if ("WEP".equals(networkType)) { networkT = NetworkType.NETWORK_WEP; } else if ("nopass".equals(networkType)) { networkT = NetworkType.NETWORK_NOPASS; } else { networkT = NetworkType.NETWORK_INVALID; } // This is not available before onCreate wifiManager = (WifiManager) this.getSystemService(WIFI_SERVICE); // Start WiFi, otherwise nothing will work wifiManager.setWifiEnabled(true); // So we know when the network changes wifiReceiver = new WifiReceiver(wifiManager, this, statusView, ssid); // The order matters! mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); mWifiStateFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mWifiStateFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); registerReceiver(wifiReceiver, mWifiStateFilter); receiverRegistered = true; if (password == null) { password = ""; } Log.d(TAG, "Adding new configuration: \nSSID: " + ssid + "Type: " + networkT); NetworkSetting setting = new NetworkSetting(ssid, password, networkT); changeNetwork(setting); } @Override public void onPause() { super.onPause(); if (receiverRegistered) { unregisterReceiver(wifiReceiver); receiverRegistered = false; } } @Override public void onResume() { super.onResume(); if (wifiReceiver != null && mWifiStateFilter != null && !receiverRegistered) { registerReceiver(wifiReceiver, mWifiStateFilter); receiverRegistered = true; } } @Override protected void onDestroy() { if (wifiReceiver != null) { if (receiverRegistered) { unregisterReceiver(wifiReceiver); receiverRegistered = false; } wifiReceiver = null; } super.onDestroy(); } /** * Update the network: either create a new network or modify an existing network * @param config the new network configuration * @param disableOthers true if other networks must be disabled * @return network ID of the connected network. */ private int updateNetwork(WifiConfiguration config, boolean disableOthers) { WifiConfiguration found = findNetworkInExistingConfig(config.SSID); wifiManager.disconnect(); if (found == null) { statusView.setText(R.string.wifi_creating_network); } else { statusView.setText(R.string.wifi_modifying_network); Log.d(TAG, "Removing network " + found.networkId); wifiManager.removeNetwork(found.networkId); wifiManager.saveConfiguration(); } networkId = wifiManager.addNetwork(config); Log.d(TAG, "Inserted/Modified network " + networkId); if (networkId < 0) { return FAILURE_NO_NETWORK_ID; } // Try to disable the current network and start a new one. if (!wifiManager.enableNetwork(networkId, disableOthers)) { networkId = FAILURE_NO_NETWORK_ID; return FAILURE_NO_NETWORK_ID; } errorCount = 0; wifiManager.reassociate(); return networkId; } }