/******************************************************************************* * Copyright 2013-2015 alladin-IT GmbH * * 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 at.alladin.rmbt.android.util.net; import java.io.IOException; import java.net.HttpURLConnection; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.URL; import java.net.UnknownHostException; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import android.util.Log; import at.alladin.rmbt.android.util.InformationCollector; /** * * @author lb * */ public class NetworkUtil { /** * */ private static final String DEBUG_TAG = "NetworkUtil"; /** * */ public static final String WALLED_GARDEN_URL = "http://webtest.nettest.at/generate_204"; /** * */ public static final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000; /** * * @author lb * * @param <T> */ public static class MinMax<T> { public T min; public T max; public MinMax(T min, T max) { this.min = min; this.max = max; } @Override public String toString() { return "MinMax [min=" + min + ", max=" + max + "]"; } } /** * * @param signalType * can (should) contain one of the following values: * <ul> * <li>{@link InformationCollector#SINGAL_TYPE_MOBILE}</li> * <li>{@link InformationCollector#SINGAL_TYPE_RSRP}</li> * <li>{@link InformationCollector#SINGAL_TYPE_WLAN}</li> * </ul> * @return */ public static MinMax<Integer> getSignalStrengthBounds(int signalType) { int min = Integer.MIN_VALUE; int max = Integer.MAX_VALUE; switch (signalType) { case InformationCollector.SINGAL_TYPE_MOBILE: min = -110; max = -50; break; case InformationCollector.SINGAL_TYPE_WLAN: min = -100; max = -40; break; case InformationCollector.SINGAL_TYPE_RSRP: min = -130; max = -70; break; } return new MinMax<Integer>(min, max); } /** * * @return */ public static boolean isWalledGardenConnection() { HttpURLConnection urlConnection = null; try { Log.i(DEBUG_TAG, "checking for walled garden..."); URL url = new URL(WALLED_GARDEN_URL); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setInstanceFollowRedirects(false); urlConnection.setConnectTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS); urlConnection.setReadTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS); urlConnection.setUseCaches(false); urlConnection.getInputStream(); Log.d(DEBUG_TAG, "check completed, response: " + urlConnection.getResponseCode()); // We got a valid response, but not from the real google return urlConnection.getResponseCode() != 204; } catch (IOException e) { e.printStackTrace(); return false; } finally { if (urlConnection != null) { urlConnection.disconnect(); } } } public static NetworkInterface46 getLocalIpAddresses(InetAddress privateIp) { try { NetworkInterface46 iface = null; for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); //if (NetworkInfoCollector.DJ_DEBUG) { System.out.println(intf.toString() + ", isUp: " + intf.isUp() + ", isLoopback: " + intf.isLoopback() + ", isP2P: " + intf.isPointToPoint() + ", isVirtual: " + intf.isVirtual() + "\n"); //} for (Enumeration<InetAddress> addrList = intf.getInetAddresses(); addrList.hasMoreElements();) { InetAddress addr = addrList.nextElement(); if (addr.equals(privateIp)) { return new NetworkInterface46(intf, false); } } } return iface; } catch (Exception ex) { ex.printStackTrace(); } return null; } /** * * @return * @throws SocketException * @throws UnknownHostException */ public static Set<InetAddress> getAllInterfaceIpAddresses() throws SocketException, UnknownHostException { Set<InetAddress> ipSet = new HashSet<InetAddress>(); for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); if (intf.getInetAddresses().hasMoreElements()) { Enumeration<InetAddress> ipAddressEnumeration = intf.getInetAddresses(); while (ipAddressEnumeration.hasMoreElements()) { ipSet.add(ipAddressEnumeration.nextElement()); } } } return ipSet; } /** * Returns the requested interface including IPv4 and (if available) IPv6 * @return */ public static NetworkInterface46 getLocalIpAddresses(boolean isLoopback) { try { NetworkInterface46 iface = null; for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); //ifaceList.add(new NetworkInterface46(intf, isLoopback)); //System.out.println(intf.toString() + " isUp: " + intf.isUp()); //xnor: if ((intf.isLoopback() == isLoopback) && intf.isUp() && intf.getInetAddresses().hasMoreElements()) { if (isLoopback) { return new NetworkInterface46(intf, isLoopback); } if (iface != null) { iface.registerNetworkIface(intf, isLoopback); } else { iface = new NetworkInterface46(intf, isLoopback); } } } return iface; } catch (Exception ex) { ex.printStackTrace(); } return null; } /** * check if there is an ipv6 in the loopback interface (=could be used to determine ipv6 support) * @return */ public static boolean isLoopbackIntefaceIpv6Available() { return isLoopbackInterfaceIpv6Available(null); } /** * check if there is an ipv6 in the loopback interface (=could be used to determine ipv6 support) * @return */ public static boolean isLoopbackInterfaceIpv6Available(NetworkInterface46 iface) { if (iface == null) { iface = getLocalIpAddresses(true); } if (iface != null) { return iface.getIpv6() != null; } return false; } /** * * @author lb * */ public static class NetworkInterface46 { private Inet4Address ipv4; private Inet6Address ipv6; private InetAddress ip; private NetworkInterface networkInterface; public NetworkInterface46(NetworkInterface networkInterface, boolean isLoopback) { registerNetworkIface(networkInterface, isLoopback); } public void registerNetworkIface(NetworkInterface networkInterface, boolean isLoopback) { this.networkInterface = networkInterface; for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (inetAddress instanceof Inet6Address) { if (ipv6 == null || (!inetAddress.isLinkLocalAddress() && (inetAddress.isLoopbackAddress() == isLoopback))) { ipv6 = (Inet6Address) inetAddress; } } else if (inetAddress instanceof Inet4Address) { if (ipv4 == null || (!inetAddress.isLinkLocalAddress() && (inetAddress.isLoopbackAddress() == isLoopback))) { ipv4 = (Inet4Address) inetAddress; } } else { ip = inetAddress; } } } public Inet4Address getIpv4() { return ipv4; } public void setIpv4(Inet4Address ipv4) { this.ipv4 = ipv4; } public Inet6Address getIpv6() { return ipv6; } public void setIpv6(Inet6Address ipv6) { this.ipv6 = ipv6; } public NetworkInterface getNetworkInterface() { return networkInterface; } public void setNetworkInterface(NetworkInterface networkInterface) { this.networkInterface = networkInterface; } @Override public String toString() { return "NetworkInterface46 [ipv4=" + ipv4 + ", ipv6=" + ipv6 + ", ip=" + ip + ", networkInterface=" + (networkInterface != null ? networkInterface : "") + ", name=" + (networkInterface != null ? networkInterface.getName() : "") + ", displayName=" + (networkInterface != null ? networkInterface.getDisplayName() : "") + "]"; } } }