android-ngn-stack/src/main/java/org/doubango/ngn/services/impl/NgnNetworkService.java
c732d49e
 /*
74ca6d11
 * Copyright (C) 2020, University of the Basque Country (UPV/EHU)
c732d49e
 *  Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
 *
 * The original file was part of Open Source IMSDROID
 *  Copyright (C) 2010-2011, Mamadou Diop.
 *  Copyright (C) 2011, Doubango Telecom.
 *
 *
 * Contact: Mamadou Diop <diopmamadou(at)doubango(dot)org>
 *
 * This file is part of Open Source Doubango Framework.
 *
 * This is free software: you can redistribute it and/or modify it under the terms of
 * the GNU General Public License as published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 *
 * This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 package org.doubango.ngn.services.impl;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
 import android.net.wifi.WifiConfiguration.GroupCipher;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 import android.widget.Toast;
 
 import org.doubango.ngn.BuildConfig;
 import org.doubango.ngn.NgnApplication;
 import org.doubango.ngn.NgnEngine;
 import org.doubango.ngn.model.NgnAccessPoint;
 import org.doubango.ngn.services.INgnNetworkService;
 import org.doubango.ngn.utils.NgnConfigurationEntry;
 import org.doubango.ngn.utils.NgnObservableList;
 import org.doubango.ngn.utils.NgnStringUtils;
 import org.doubango.utils.Utils;
 
 import java.io.IOException;
 import java.lang.reflect.Method;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 /**@page NgnNetworkService_page Network Service
  * The network service is used to manage both WiFi and 3g/4g network connections.
  */
 
 public class NgnNetworkService  extends NgnBaseService implements INgnNetworkService {
 	private static final String TAG = Utils.getTAG(NgnNetworkService.class.getCanonicalName());
 	
 	private static final String OPENVPN_INTERFACE_NAME = "tun0";
 	@SuppressWarnings("unused")
 	private static final String WLAN_INTERFACE_NAME = "wlan0";
 	private static final String USB_INTERFACE_NAME = "usb0";
 	
 	private WifiManager mWifiManager;
 	private WifiLock mWifiLock;
 	private String mConnetedSSID;
 	private boolean mAcquired;
 	private boolean mStarted;
 	private boolean mScanning;
 	private final NgnObservableList<NgnAccessPoint> mAccessPoints;
 	private BroadcastReceiver mNetworkWatcher;
 	
 	private static int WifiManager_WIFI_MODE = WifiManager.WIFI_MODE_FULL;
 	private static int ConnectivityManager_TYPE_ETHERNET = 0x00000009;
 	private static int ConnectivityManager_TYPE_WIMAX = 0x00000006;
 	private static Method NetworkInterface_isUp;
 	
 	static{
 		final int sdkVersion = NgnApplication.getSDKVersion();
 		if(sdkVersion >= 9){
 			try {
 				WifiManager_WIFI_MODE = WifiManager.class.getDeclaredField("WIFI_MODE_FULL_HIGH_PERF").getInt(null);
 			} catch (Exception e) {
 				Log.e(TAG, e.toString());
 			}
 		}
 		if(sdkVersion >= 13){
 			try {
 				ConnectivityManager_TYPE_ETHERNET = ConnectivityManager.class.getDeclaredField("TYPE_ETHERNET").getInt(null);
 			} catch (Exception e) {
 				Log.e(TAG, e.toString());
 			}
 		}
 		
 		if(sdkVersion >= 8){
 			try {
 				ConnectivityManager_TYPE_WIMAX = ConnectivityManager.class.getDeclaredField("TYPE_WIMAX").getInt(null);
 			} catch (Exception e) {
 				Log.e(TAG, e.toString());
 			}
 		}
 		
 		// according to the documentation, NetworkInterface::isUp() is only defined starting API Level 9 but it's available on my GS1 (API Level 8)
 		// this is why we don't test sdk version
 		try{
 			NetworkInterface_isUp = NetworkInterface.class.getDeclaredMethod("isUp");
 		}
 		catch (Exception e) { }
 	}
 	
 	public static final int[] sWifiSignalValues = new int[] {
         0,
         1,
         2,
         3,
         4
     };
 	
 	public static enum DNS_TYPE {
 		DNS_1, DNS_2, DNS_3, DNS_4
 	}
 	
 	public NgnNetworkService() {
 		super();
 		
 		mAccessPoints = new NgnObservableList<NgnAccessPoint>(true);
 	}
 	
 	@Override
 	public boolean start() {
 		Log.d(TAG, "Starting...");
 		mWifiManager = (WifiManager) NgnApplication.getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
 		
 		if(mWifiManager == null){
 			Log.e(TAG, "WiFi manager is Null.");
 			return false;
 		}
 		
 		mStarted = true;
 		return true;
 	}
 
 	@Override
 	public boolean stop() {
 		Log.d(TAG, "Stopping...");
 		if(!mStarted){
 			Log.w(TAG, "Not started...");
 			return false;
 		}
 		
 		if(mNetworkWatcher != null){
 			NgnApplication.getContext().unregisterReceiver(mNetworkWatcher);
 			mNetworkWatcher = null;
 		}
 		
 		release();
 		mStarted = false;
 		return true;
 	}
 
 	@Override
 	public String getDnsServer(DNS_TYPE type) {
 		String dns = null;
 		switch (type) {
 			case DNS_1: default: dns = "dns1"; break;
 			case DNS_2: dns = "dns2"; break;
 			case DNS_3: dns = "dns3"; break;
 			case DNS_4: dns = "dns4"; break;
 		}
 
 		if (mWifiManager != null) {
 			String[] dhcpInfos = mWifiManager.getDhcpInfo().toString().split(" ");
 			int i = 0;
 
 			while (i++ < dhcpInfos.length) {
 				if (dhcpInfos[i - 1].equals(dns)) {
 					return dhcpInfos[i];
 				}
 			}
 		}
 		return null;
 	}
 
 	@Override
 	public String getLocalIP(boolean ipv6) {
 		final HashMap<String, InetAddress> addressMap = new HashMap<String, InetAddress>();
 		
 		try {
 			for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
 				final NetworkInterface intf = en.nextElement();
 				
 				// http://code.google.com/p/imsdroid/issues/detail?id=398#c3
 				try{
 					if(NetworkInterface_isUp != null && !(Boolean)NetworkInterface_isUp.invoke(intf)){
 						Log.i(TAG, "interface=" + intf.getName() + " is not up");
 						continue;
 					}
 				}
 				catch(Exception e){}
 				
 				for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
 					InetAddress inetAddress = enumIpAddr.nextElement();
 					Log.d(NgnNetworkService.TAG, inetAddress.getHostAddress().toString());
 					if(inetAddress.isLoopbackAddress() || ((inetAddress instanceof Inet6Address) && ((Inet6Address)inetAddress).isLinkLocalAddress())){
 			    		continue;
 			    	}
 					if (((inetAddress instanceof Inet4Address) && !ipv6) || ((inetAddress instanceof Inet6Address) && ipv6)) {
 						addressMap.put(intf.getName(), inetAddress);
 					}
 				}
 			}
 			if(addressMap.size() > 0){
 				// openvpn address
 				final InetAddress openvpn = addressMap.get(OPENVPN_INTERFACE_NAME);
 				if(openvpn != null){
 					final String openvpnAddr = openvpn.getHostAddress().toString();
 					if(!NgnStringUtils.isNullOrEmpty(openvpnAddr)){
 						return openvpnAddr;
 					}
 				}
 				
 				final Iterator<Map.Entry<String, InetAddress>> it = addressMap.entrySet().iterator();
 				Map.Entry<String, InetAddress> kvp;
 			    while (it.hasNext()) {
 			    	kvp = it.next();
 			    	final InetAddress address = kvp.getValue();
 			    	if(kvp.getKey().equals(USB_INTERFACE_NAME)){
 			    		continue;
 			    	}
 				    return address.getHostAddress();
 			    }
 				return addressMap.values().iterator().next().getHostAddress();
 			}
 		} catch (SocketException ex) {
 			Log.e(NgnNetworkService.TAG, ex.toString());
 		}
 
 		// Hack
 		try {
 			java.net.Socket socket = new java.net.Socket(ipv6 ? "ipv6.google.com" : "google.com", 80);
 			Log.d(NgnNetworkService.TAG, socket.getLocalAddress().getHostAddress());
 			return socket.getLocalAddress().getHostAddress();
 		} catch (UnknownHostException e) {
 			Log.e(NgnNetworkService.TAG, e.toString());
 		} catch (IOException e) {
 			Log.e(NgnNetworkService.TAG, e.toString());
 		} catch (Exception e){
 			Log.e(NgnNetworkService.TAG, e.toString());
 		}
 
 		return null;
 	}
 
 	@Override
 	public boolean isScanning(){
 		return mScanning;
 	}
 	
 	@Override
 	public boolean setNetworkEnabledAndRegister() {
 		// TODO Auto-generated method stub
 		return false;
 	}
 
 	@Override
 	public boolean setNetworkEnabled(String SSID, boolean enabled, boolean force) {
 		return setNetworkEnabled(getNetworkIdBySSID(SSID), enabled, force);
 	}
 	
 	@Override
 	public boolean setNetworkEnabled(int networkId, boolean enabled, boolean force){
 		Log.d(TAG, "setNetworkEnabled(" + enabled + ")");
 		
 		if(mWifiManager == null){
 			Log.e(TAG, "WiFi manager is Null");
 			return false;
 		}
 		
 		final boolean useWifi = NgnEngine.getInstance().getConfigurationService().getBoolean(
 				NgnConfigurationEntry.NETWORK_USE_WIFI, NgnConfigurationEntry.DEFAULT_NETWORK_USE_WIFI);
 
 		if (useWifi) {
 			boolean ret = false;
 			if ((force || !mWifiManager.isWifiEnabled()) && enabled) {
 				Toast.makeText(NgnApplication.getContext(), "Trying to start WiFi",
 						Toast.LENGTH_SHORT).show();
 				ret = mWifiManager.setWifiEnabled(true);
 				if (ret && networkId>=0) {
 					ret = mWifiManager.enableNetwork(networkId, true);
 				}
 			} else if ((force || mWifiManager.isWifiEnabled()) && !enabled) {
 				Toast.makeText(NgnApplication.getContext(), "Trying to stop WiFi",
 						Toast.LENGTH_SHORT).show();
 				ret = mWifiManager.setWifiEnabled(false);
 				if (ret && networkId>=0) {
 					ret = mWifiManager.disableNetwork(networkId);
 				}
 			}
 			return ret;
 		}
 		else{
 			Log.w(TAG, "setNetworkEnabled() is called but WiFi not enabled");
 		}
 		return false;
 	}
 
 	@Override
 	public boolean forceConnectToNetwork() {
 		// TODO Auto-generated method stub
 		return false;
 	}
 	
 	@Override
 	public NgnObservableList<NgnAccessPoint> getAccessPoints(){
 		return mAccessPoints;
 	}
 
 	@Override
 	public int configure(NgnAccessPoint ap, String password, boolean bHex){
 		if(ap == null){
 			Log.e(TAG, "Null AccessPoint");
 			return -1;
 		}
 		else if(ap.isConfigured()){
 			Log.w(TAG, "AccessPoint already configured");
 			return -1;
 		}
 		else if(ap.getSR() == null){
 			Log.e(TAG, "Null SR");
 		}
 		else if(mWifiManager == null){
 			Log.e(TAG, "Null WifiManager");
 			return -1;
 		}
 		
 		final ScanResult sr = ap.getSR();
 		WifiConfiguration wConf = new WifiConfiguration();
 		//http://developer.android.com/reference/android/net/wifi/WifiConfiguration.html#SSID
 		wConf.SSID = "\"" + sr.SSID + "\"";
 		wConf.BSSID = sr.BSSID;
 		wConf.priority = 40;
 		String security = NgnAccessPoint.getScanResultSecurity(sr);
 		if(security == NgnAccessPoint.AP_WEP){
 			wConf.wepKeys[0] = bHex ? password : NgnStringUtils.quote(password, "\"");//hex not quoted
             
 			wConf.wepTxKeyIndex = 0;
             
             wConf.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
             wConf.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
 
             wConf.allowedKeyManagement.set(KeyMgmt.NONE);
             
             wConf.allowedGroupCiphers.set(GroupCipher.WEP40);
             wConf.allowedGroupCiphers.set(GroupCipher.WEP104);
 		}
 		else if(security == NgnAccessPoint.AP_WPA || security == NgnAccessPoint.AP_WPA2){
 			wConf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);  
 			wConf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);  
 			wConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);  
 			wConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);  
 			wConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);  
 			wConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);  
 			wConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);  
 			wConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);  
 			wConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);  
 			wConf.preSharedKey = "\"".concat(BuildConfig.APP_NAME_PROPIETARY).concat("\"");
 		}
 		else if(security == NgnAccessPoint.AP_OPEN){
 			wConf.allowedKeyManagement.set(KeyMgmt.NONE);
 		}
 		return mWifiManager.addNetwork(wConf);
 	}
 	
 	@Override
 	public boolean scan(){
 		if(mWifiManager == null){
 			Log.e(TAG,"WiFi manager is Null");
 			return false;
 		}
 		
 		Toast.makeText(NgnApplication.getContext(), "Network Scanning...", Toast.LENGTH_SHORT).show();
 		
 		if(mNetworkWatcher == null){
 			IntentFilter intentNetWatcher = new IntentFilter();
 			intentNetWatcher.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
 			intentNetWatcher.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
 			intentNetWatcher.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
 			intentNetWatcher.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
 			intentNetWatcher.addAction(WifiManager.RSSI_CHANGED_ACTION);
 			mNetworkWatcher = new BroadcastReceiver() {
 				@Override
 				public void onReceive(Context context, Intent intent) {
 					handleNetworkEvent(context, intent);
 				}
 			};
 			NgnApplication.getContext().registerReceiver(mNetworkWatcher, intentNetWatcher);
 		}
 		
 		mScanning = true;
 		if(mWifiManager.setWifiEnabled(true)){
 			return mWifiManager.reassociate();
 		}
 		return false;
 	}
 	
 	@Override
 	public boolean acquire() {
 		if (mAcquired) {
 			return true;
 		}
 		
175b478c
 		if(BuildConfig.DEBUG)Log.d(TAG, "acquireNetworkLock()");
c732d49e
 
 		boolean connected = false;
 		NetworkInfo networkInfo = NgnApplication.getConnectivityManager().getActiveNetworkInfo();
 		if (networkInfo == null) {
 			Log.e(NgnNetworkService.TAG, "Failed to get Network information");
 			return false;
 		}
 
 		int netType = networkInfo.getType();
 		int netSubType = networkInfo.getSubtype();
 
 		Log.d(NgnNetworkService.TAG, String.format("netType=%d and netSubType=%d",
 				netType, netSubType));
 
 		boolean useWifi = NgnEngine.getInstance().getConfigurationService().getBoolean(NgnConfigurationEntry.NETWORK_USE_WIFI, 
 				NgnConfigurationEntry.DEFAULT_NETWORK_USE_WIFI);
 		boolean use3G = NgnEngine.getInstance().getConfigurationService().getBoolean(NgnConfigurationEntry.NETWORK_USE_3G,
 				NgnConfigurationEntry.DEFAULT_NETWORK_USE_3G);
 
 		if (useWifi && (netType == ConnectivityManager.TYPE_WIFI) && mWifiLock == null) {
 			if (mWifiManager != null && mWifiManager.isWifiEnabled()) {
 				mWifiLock = mWifiManager.createWifiLock(NgnNetworkService.WifiManager_WIFI_MODE, NgnNetworkService.TAG);
 				final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
 				if (wifiInfo != null && mWifiLock != null) {
 					final DetailedState detailedState = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState());
 					if (detailedState == DetailedState.CONNECTED
 							|| detailedState == DetailedState.CONNECTING
 							|| detailedState == DetailedState.OBTAINING_IPADDR) {
 						mWifiLock.acquire();
 						mConnetedSSID = wifiInfo.getSSID();
 						connected = true;
 					}
 				}
 			} else {
 				Log.d(NgnNetworkService.TAG, "WiFi not enabled");
 			}
 		} else if (use3G && (netType == ConnectivityManager.TYPE_MOBILE || netType == ConnectivityManager_TYPE_WIMAX)) {
 			if ((netSubType >= TelephonyManager.NETWORK_TYPE_UMTS)
 					|| // HACK
 					(netSubType == TelephonyManager.NETWORK_TYPE_GPRS)
 					|| (netSubType == TelephonyManager.NETWORK_TYPE_EDGE)) {
 				//Toast.makeText(WiPhone.getContext(),
 				//		"Using 2.5G (or later) network", Toast.LENGTH_SHORT)
 				//		.show();
 				connected = true;
 			}
 		}
 		else if (netType == ConnectivityManager_TYPE_ETHERNET) {
 			// Ethernet always accepted
 			connected = true;
 		}
 
 		if (!connected) {
 			Log.e(NgnNetworkService.TAG, "No active network");
 			return false;
 		}
 
 		mAcquired = true;
 		return true;
 	}
 
 	@Override
 	public boolean release() {
175b478c
 			try {
 				if (mWifiLock != null) {
 					if(mWifiLock.isHeld()){
 						Log.d(TAG, "releaseNetworkLock()");
 						mWifiLock.release();
 					}
c732d49e
 
175b478c
 				}
 			}catch (Exception e){
 				Log.e(TAG,"Error in Lock Wifi:"+e.getMessage());
 			}finally {
 				mWifiLock = null;
 			}
c732d49e
 		mAcquired = false;
 		return true;
 	}
 	
 	private int getNetworkIdBySSID(String SSID) {
 		synchronized(mAccessPoints){
 			final NgnAccessPoint ap = getAccessPointBySSID(SSID);
 			if(ap != null){
 				return ap.getNetworkId();
 			}
 			return -1;
 		}
 	}
 
 	@SuppressWarnings("unused")
 	private WifiConfiguration getWifiConfBySSID(String SSID) {
 		synchronized(mAccessPoints){
 			final NgnAccessPoint ap = getAccessPointBySSID(SSID);
 			if(ap != null){
 				return ap.getConf();
 			}
 			return null;
 		}
 	}
 	
 	private NgnAccessPoint getAccessPointBySSID(String SSID) {
 		final List<NgnAccessPoint> accessPoints = mAccessPoints.getList();
 		for (NgnAccessPoint ap : accessPoints) {
 			String SSID1 = NgnStringUtils.unquote(ap.getSSID(), "\"");
 			String SSID2 = NgnStringUtils.unquote(SSID, "\"");
 			if (SSID1.equalsIgnoreCase(SSID2)) {
 				return ap;
 			}
 		}
 		return null;
 	}
 	
 	private void loadConfiguredNetworks(){
 		synchronized(mAccessPoints){
 			mAccessPoints.clear();
 			final List<WifiConfiguration> confNetworks = mWifiManager.getConfiguredNetworks();
 			for (WifiConfiguration wifiConf : confNetworks) {
 				NgnAccessPoint ap = new NgnAccessPoint(wifiConf);
 				ap.setConnected(NgnStringUtils.equals(mConnetedSSID, ap.getSSID(), false));
 				mAccessPoints.add(ap);
 			}
 		}
 	}
 	
 	private void handleNetworkEvent(Context context, Intent intent){
 		final String action = intent.getAction();
 		Log.d(TAG, "NetworkService::BroadcastReceiver(" + action + ")");
 		
 		if(mWifiManager == null){
 			Log.e(TAG, "Invalid state");
 			return;
 		}
 		
 		if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
 			mScanning = true;
 			// load() configured networks
 			loadConfiguredNetworks();
 			// load() network results
 			synchronized(mAccessPoints){
 				List<ScanResult> scanResults = mWifiManager.getScanResults();
 				for(ScanResult sr : scanResults){
 					NgnAccessPoint ap = getAccessPointBySSID(sr.SSID);
 					if(ap == null){
 						ap = new NgnAccessPoint(sr);
 						mAccessPoints.add(ap);
 					}
 				}
 			}
 			
 			updateConnectionState();
 			mScanning = false;
 		}
 		else if(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION.equals(action)){
 			final boolean connected = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false);
 			Log.d(TAG, "SUPPLICANT_CONNECTION_CHANGE_ACTION.CONNECTED="+connected);
 			if(connected){
 				final WifiInfo wInfo = mWifiManager.getConnectionInfo();
 				if(wInfo != null){
 					if(!NgnStringUtils.equals(mConnetedSSID, wInfo.getSSID(), false)){
 						triggerSipRegistration();
 					}
 					mConnetedSSID = wInfo.getSSID();
 				}
 			}
 			updateConnectionState();
 //			synchronized(mAccessPoints){
 //				final List<AccessPoint> aps = mAccessPoints.getList();
 //				for(AccessPoint ap : aps){
 //					ap.setConnected(connected && StringUtils.equals(mConnetedSSID, ap.getSSID(), false));
 //				}
 //			}
 		}
 		else if(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)){
 			updateConnectionState();
 //			final SupplicantState newState = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
 //			if(newState != null){
 //				synchronized(mAccessPoints){
 //					final List<AccessPoint> aps = mAccessPoints.getList();
 //					final WifiInfo wInfo = mWifiManager.getConnectionInfo();
 //					if(wInfo != null){
 //						for(AccessPoint ap : aps){
 //							ap.setConnected((newState == SupplicantState.ASSOCIATED) && StringUtils.equals(wInfo.getSSID(), ap.getSSID(), false));
 //						}
 //					}
 //				}
 //			}
 		}
 		else if(WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)){
 			updateConnectionState();
 //			final boolean connected = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)
 //				== WifiManager.WIFI_STATE_ENABLED;
 //			synchronized(mAccessPoints){
 //				final List<AccessPoint> aps = mAccessPoints.getList();
 //				final WifiInfo wInfo = mWifiManager.getConnectionInfo();
 //				if(wInfo != null){
 //					for(AccessPoint ap : aps){
 //						ap.setConnected(connected && StringUtils.equals(wInfo.getSSID(), ap.getSSID(), false));
 //					}
 //				}
 //			}
 		}
 		else if(WifiManager.RSSI_CHANGED_ACTION.equals(action)){
 			final WifiInfo wInfo = mWifiManager.getConnectionInfo();
 			if(wInfo != null){
 				final NgnAccessPoint ap = getAccessPointBySSID(wInfo.getSSID());
 				if(ap != null){
 					final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
 					ap.setLevel(WifiManager.calculateSignalLevel(newRssi,
 							sWifiSignalValues.length));
 				}
 			}
 		}
 	}
 	
 	private void updateConnectionState(){
 		final WifiInfo wInfo = mWifiManager.getConnectionInfo();
 		boolean bAtLeastOneConnected = false;
 		if(wInfo != null){
 			final DetailedState detailedState = WifiInfo
 				.getDetailedStateOf(wInfo.getSupplicantState());
 			boolean isConnecting = detailedState == DetailedState.CONNECTED
 			|| detailedState == DetailedState.CONNECTING
 			|| detailedState == DetailedState.OBTAINING_IPADDR;
 			synchronized(mAccessPoints){
 				final List<NgnAccessPoint> aps = mAccessPoints.getList();
 				if(wInfo != null){
 					for(NgnAccessPoint ap : aps){
 						final boolean connected = isConnecting && NgnStringUtils.equals(wInfo.getSSID(), ap.getSSID(), false);
 						ap.setConnected(connected);
 						bAtLeastOneConnected |= connected;
 					}
 				}
 			}
 		}
 		
 		if(bAtLeastOneConnected || !NgnEngine.getInstance().getSipService().isRegistered()){
 			triggerSipRegistration();
 		}
 		
 	}
 	
 	private void triggerSipRegistration(){
 //		new Thread(new Runnable() {
 //			@Override
 //			public void run() {
 //				Log.d(TAG, "Network connection chaged: restart the stack");
 //				final ISipService sipService = ServiceManager.getSipService();
 //				final ConnectionState registrationState = sipService.getRegistrationState();
 //				switch(registrationState){
 //					case NONE:
 //					case TERMINATED:
 //						sipService.register(null);
 //						break;
 //					case CONNECTING:
 //					case TERMINATING:
 //					case CONNECTED:
 //						sipService.unRegister();
 //						sipService.register(null);
 //						break;
 //				}
 //			}
 //		}).start();
 	}
 	@Override
 	public boolean clearService(){
 		return true;
 	}
 }