Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3a6ced7c authored by sanketk's avatar sanketk Committed by Steve Kondik
Browse files

Tethering: Enable NAT only when tether and upstream ifaces are different.

When enabling WIFI hostspot, chooseUpStreamInterface will choose WIFI
interface as it is still up. It will result in both tethered and upsteam
interfaces are same one. netd will reject this command and tethering
will fail this time.

This fix will not send NAT command to netd when it found these two
interfaces are same one. Later when the real upstream interface is
brought up by ConnetivityService, Tethering.java will continue the NAT
procedure.

CRs-Fixed: 692285
Change-Id: I1ecd700ad64748c3745fffc76b7ac0e7d7b9b96b

Telephony: Avoid Infinite loop problem in Tethering

1. Whenever data is enabled we will try to establish the tethered
call (USB tethering enabled case) for 5 fixed number of retries.
After reaching maximum number of retries we are turning off the
upstream connection. whenever the CONNECTIVTY_ACTION received
(because of USB cable disconnected and then connected case or
some changes), it can try to bring up the dun/hipri PDP again.

2. There is no retry in case of data disabled case.

Change-Id: I16af4d2983a8bf9ce0ce904877f86169bca549b4
CRs-Fixed: 401829
(cherry picked from commit 4c923c8537fdc49ef491b964adc1871c77bfd730)
(cherry picked from commit 3135e6a89ac14008df04fe6e068bd8dd95b4ee40)
(cherry picked from commit 137b7004f716a559c7249be20e25544fe10330b6)

Broadcast tethered client inteface along with upstream interface name

On change in tethering upstream interface for IPV4 of IPV6 address,
broadcast an intent with both tethered client interface as well as
upstream interface name, ip address type and update type.

Change-Id: I2f23e2b8ec125339bedd454446accb23e33cacae

base: Add P2P interface "p2p0" to tethering support list

Dnsmasq is running as singleton pattern, P2P GO start DHCP server fail
if dnsmasq has been started by USB tethering. Tethering management
feature in Tethering.java just support soft AP and USB tethering. Add
P2P interface "p2p0" to tethering support list.

CRs-Fixed: 719930
Change-Id: If3a07e6cac1678dfedf361abf99f52bc12a2f697

base: Fix for wifi tethering crash

Pass network info along with CMD_UPSTREAM_CHANGED
Added a NULL check for Network info in CMD_UPSTREAM_CHANGED

CRs-fixed: 562910
Change-Id: I98bd37205255d9d4025cfb95b0688c68bce3c9bd

Tether: fix the retry issue in Tethering

Since StartUsingNetworkFeature will always return success, it's
not a good place to set retry. With this modification, the retry
will work.

Change-Id: Ia2ea489ea57f99617004093bfedc8e7e6dba46ed
CRs-fixed: 667865
parent d5d5d1b7
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -249,6 +249,14 @@
    <string-array translatable="false" name="config_tether_wifi_regexs">
    </string-array>

    <!-- List of regexpressions describing the interface (if any) that represent tetherable
         p2p Go interfaces.  If the device doesn't want to support tethering over P2p this
         should be empty. -->
    <string-array translatable="false" name="config_tether_p2p_regexs">
        <item>"p2p0"</item>
    </string-array>


    <!-- List of regexpressions describing the interface (if any) that represent tetherable
         WiMAX interfaces.  If the device doesn't want to support tethering over Wifi this
         should be empty.  An example would be "softap.*" -->
+1 −0
Original line number Diff line number Diff line
@@ -1476,6 +1476,7 @@
  <java-symbol type="array" name="config_tether_upstream_types" />
  <java-symbol type="array" name="config_tether_usb_regexs" />
  <java-symbol type="array" name="config_tether_wifi_regexs" />
  <java-symbol type="array" name="config_tether_p2p_regexs" />
  <java-symbol type="array" name="config_usbHostBlacklist" />
  <java-symbol type="array" name="config_serialPorts" />
  <java-symbol type="array" name="radioAttributes" />
+111 −38
Original line number Diff line number Diff line
@@ -71,6 +71,9 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import static libcore.io.OsConstants.AF_INET;
import static libcore.io.OsConstants.AF_INET6;

/**
 * @hide
 *
@@ -90,9 +93,12 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
    public static final String UPSTREAM_IFACE_CHANGED_ACTION =
                         "com.android.server.connectivity.UPSTREAM_IFACE_CHANGED";

    // Upstream Interface Name i.e rmnet_data0, wlan0 etc
    // Upstream Interface Name i.e. rmnet_data0, wlan0 etc.
    public static final String EXTRA_UPSTREAM_IFACE = "tetheringUpstreamIface";

    // Tethered Interface Name i.e. rndis0, wlan0, usb0 etc.
    public static final String EXTRA_TETHERED_IFACE = "tetheredClientIface";

    // Upstream Interface IP Type i.e IPV6 or IPV4
    public static final String EXTRA_UPSTREAM_IP_TYPE = "tetheringUpstreamIpType";

@@ -102,8 +108,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
    // Default Value for Extra Infomration
    public static final int EXTRA_UPSTREAM_INFO_DEFAULT = -1;

    private enum IPAddrType { V4, V6 }

    private enum UpstreamInfoUpdateType {
        UPSTREAM_IFACE_REMOVED,
        UPSTREAM_IFACE_ADDED
@@ -112,6 +116,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
    // TODO - remove both of these - should be part of interface inspection/selection stuff
    private String[] mTetherableUsbRegexs;
    private String[] mTetherableWifiRegexs;
    private String[] mTetherableP2pRegexs;
    private String[] mTetherableBluetoothRegexs;
    private Collection<Integer> mUpstreamIfaceTypes;

@@ -145,11 +150,13 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
    // with 255.255.255.0

    private String[] mDhcpRange;
    private static final int TETHER_RETRY_UPSTREAM_LIMIT = 5;
    // P2p GO is 192.168.49.1 and 255.255.255.0
    private static final String[] DHCP_DEFAULT_RANGE = {
        "192.168.42.2", "192.168.42.254", "192.168.43.2", "192.168.43.254",
        "192.168.44.2", "192.168.44.254", "192.168.45.2", "192.168.45.254",
        "192.168.46.2", "192.168.46.254", "192.168.47.2", "192.168.47.254",
        "192.168.48.2", "192.168.48.254",
        "192.168.48.2", "192.168.48.254", "192.168.49.2", "192.168.49.254"
    };

    private String[] mDefaultDnsServers;
@@ -226,6 +233,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                com.android.internal.R.array.config_tether_usb_regexs);
        String[] tetherableWifiRegexs = mContext.getResources().getStringArray(
                com.android.internal.R.array.config_tether_wifi_regexs);
        String[] tetherableP2pRegexs = mContext.getResources().getStringArray(
                com.android.internal.R.array.config_tether_p2p_regexs);
        String[] tetherableBluetoothRegexs = mContext.getResources().getStringArray(
                com.android.internal.R.array.config_tether_bluetooth_regexs);

@@ -264,6 +273,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        synchronized (mPublicSync) {
            mTetherableUsbRegexs = tetherableUsbRegexs;
            mTetherableWifiRegexs = tetherableWifiRegexs;
            mTetherableP2pRegexs = tetherableP2pRegexs;
            mTetherableBluetoothRegexs = tetherableBluetoothRegexs;
            mUpstreamIfaceTypes = upstreamIfaceTypes;
        }
@@ -279,6 +289,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        synchronized (mPublicSync) {
            if (isWifi(iface)) {
                found = true;
            } else if (isP2p(iface)) {
                found = true;
            } else if (isUsb(iface)) {
                found = true;
                usb = true;
@@ -330,6 +342,15 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        }
    }

    public boolean isP2p(String iface) {
        synchronized (mPublicSync) {
            for (String regex : mTetherableP2pRegexs) {
                if (iface.matches(regex)) return true;
            }
            return false;
        }
    }

    public boolean isBluetooth(String iface) {
        synchronized (mPublicSync) {
            for (String regex : mTetherableBluetoothRegexs) {
@@ -347,6 +368,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
            if (isWifi(iface)) {
                found = true;
            }
            if (isP2p(iface)) {
                found = true;
            }
            if (isUsb(iface)) {
                found = true;
                usb = true;
@@ -456,6 +480,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        ArrayList<String> erroredList = new ArrayList<String>();

        boolean wifiTethered = false;
        boolean p2pTethered = false;
        boolean usbTethered = false;
        boolean bluetoothTethered = false;

@@ -473,6 +498,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                            usbTethered = true;
                        } else if (isWifi((String)iface)) {
                            wifiTethered = true;
                        } else if (isP2p((String)iface)) {
                            p2pTethered = true;
                        } else if (isBluetooth((String)iface)) {
                            bluetoothTethered = true;
                        }
@@ -527,17 +554,19 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        }
    }

    private void sendUpstreamIfaceChangeBroadcast( String upstreamIface,
                                                   IPAddrType ip_type, UpstreamInfoUpdateType update_type) {
    private void sendUpstreamIfaceChangeBroadcast( String upstreamIface, String tetheredIface,
                                                   int ip_type,
                                                   UpstreamInfoUpdateType update_type) {
        if (DBG) Log.d(TAG, "sendUpstreamIfaceChangeBroadcast upstreamIface:" + upstreamIface +
                            " tetheredIface:" + tetheredIface +
                            " IP Type: "+ ip_type + " update_type" + update_type);
        Intent intent = new Intent(UPSTREAM_IFACE_CHANGED_ACTION);
        intent.putExtra(EXTRA_UPSTREAM_IFACE, upstreamIface);
        intent.putExtra(EXTRA_UPSTREAM_IP_TYPE, ip_type.ordinal());
        intent.putExtra(EXTRA_TETHERED_IFACE, tetheredIface);
        intent.putExtra(EXTRA_UPSTREAM_IP_TYPE, ip_type);
        intent.putExtra(EXTRA_UPSTREAM_UPDATE_TYPE, update_type.ordinal());

        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
        if (VDBG) Log.d(TAG, "sendUpstreamIfaceChangeBroadcast: Intent broadcasted");
    }

    private void showTetheredNotification(int icon) {
@@ -755,6 +784,10 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        return mTetherableWifiRegexs;
    }

    public String[] getTetherableP2pRegexs() {
        return mTetherableP2pRegexs;
    }

    public String[] getTetherableBluetoothRegexs() {
        return mTetherableBluetoothRegexs;
    }
@@ -1018,6 +1051,12 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
            }
        }

        public String getTethered() {
            synchronized (Tethering.this.mPublicSync) {
                return mIfaceName;
            }
        }

        private void setTethered(boolean tethered) {
            synchronized (Tethering.this.mPublicSync) {
                mTethered = tethered;
@@ -1149,9 +1188,12 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                        if (VDBG) Log.e(TAG, "Exception in forceUpdate: " + e.toString());
                    }
                    try {
                        if(VDBG) Log.d(TAG, "Disabling NAT - Tethered Iface = " + mIfaceName +
                                            " mMyUpstreamIfaceName= " + mMyUpstreamIfaceName);
                        mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
                        // Send intent to CNE Service
                        sendUpstreamIfaceChangeBroadcast( mMyUpstreamIfaceName, IPAddrType.V4,
                        sendUpstreamIfaceChangeBroadcast( mMyUpstreamIfaceName,
                                                     mIfaceName,
                                                     AF_INET,
                                                     UpstreamInfoUpdateType.UPSTREAM_IFACE_REMOVED);
                    } catch (Exception e) {
                        if (VDBG) Log.e(TAG, "Exception in disableNat: " + e.toString());
@@ -1196,16 +1238,22 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                        String newUpstreamIfaceName = (String)(message.obj);
                        if ((mMyUpstreamIfaceName == null && newUpstreamIfaceName == null) ||
                                (mMyUpstreamIfaceName != null &&
                                mMyUpstreamIfaceName.equals(newUpstreamIfaceName))) {
                                mMyUpstreamIfaceName.equals(newUpstreamIfaceName)) ||
                                (newUpstreamIfaceName != null &&
                                newUpstreamIfaceName.equals(mIfaceName))) {
                            if (VDBG) Log.d(TAG, "Connection changed noop - dropping");
                            break;
                        }
                        cleanupUpstream();
                        if (newUpstreamIfaceName != null) {
                            try {
                                if(VDBG) Log.d(TAG,"Enabling NAT - Tethered Iface = " + mIfaceName +
                                                   " newUpstreamIfaceName =" +newUpstreamIfaceName);
                                mNMService.enableNat(mIfaceName, newUpstreamIfaceName);
                                // Send intent to CNE Service
                                sendUpstreamIfaceChangeBroadcast( newUpstreamIfaceName, IPAddrType.V4,
                                sendUpstreamIfaceChangeBroadcast(
                                                       newUpstreamIfaceName,
                                                       mIfaceName,
                                                       AF_INET,
                                                       UpstreamInfoUpdateType.UPSTREAM_IFACE_ADDED);
                            } catch (Exception e) {
                                Log.e(TAG, "Exception enabling Nat: " + e.toString());
@@ -1323,6 +1371,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {

        private String mUpstreamIfaceName = null;

        protected int mRetryCount;

        private static final int UPSTREAM_SETTLE_TIME_MS     = 10000;
        private static final int CELL_CONNECTION_RENEW_MS    = 40000;

@@ -1460,8 +1510,10 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                Log.d(TAG, "adding v6 interface " + iface);
                try {
                    service.addUpstreamV6Interface(iface);
                    sendUpstreamIfaceChangeBroadcast( iface, IPAddrType.V6,
                    for (TetherInterfaceSM sm : mNotifyList) {
                        sendUpstreamIfaceChangeBroadcast( iface, sm.getTethered(), AF_INET6,
                                UpstreamInfoUpdateType.UPSTREAM_IFACE_ADDED);
                    }
                } catch (RemoteException e) {
                    Log.e(TAG, "Unable to append v6 upstream interface");
                }
@@ -1474,8 +1526,10 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                Log.d(TAG, "removing v6 interface " + iface);
                try {
                    service.removeUpstreamV6Interface(iface);
                    sendUpstreamIfaceChangeBroadcast( iface, IPAddrType.V6,
                    for (TetherInterfaceSM sm : mNotifyList) {
                        sendUpstreamIfaceChangeBroadcast( iface, sm.getTethered(), AF_INET6,
                                UpstreamInfoUpdateType.UPSTREAM_IFACE_REMOVED);
                    }
                } catch (RemoteException e) {
                    Log.e(TAG, "Unable to remove v6 upstream interface");
                }
@@ -1545,6 +1599,10 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                            + mPreferredUpstreamMobileApn + ", got type=" + upType);
                }

                if (upType != ConnectivityManager.TYPE_NONE) {
                    mRetryCount = 0;
                }

                // if we're on DUN, put our own grab on it
                if (upType == ConnectivityManager.TYPE_MOBILE_DUN ||
                        upType == ConnectivityManager.TYPE_MOBILE_HIPRI) {
@@ -1560,15 +1618,30 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                }

                if (upType == ConnectivityManager.TYPE_NONE) {
                    try {
                        if (cm.getMobileDataEnabled()) {
                            boolean tryAgainLater = true;
                            if (mRetryCount < TETHER_RETRY_UPSTREAM_LIMIT) {
                                if ((tryCell == TRY_TO_SETUP_MOBILE_CONNECTION) &&
                            (turnOnUpstreamMobileConnection(mPreferredUpstreamMobileApn) == true)) {
                                         (turnOnUpstreamMobileConnection
                                                (mPreferredUpstreamMobileApn) == true)) {
                                    // we think mobile should be coming up - don't set a retry
                                    tryAgainLater = false;
                                    mRetryCount++;
                                }
                                if (tryAgainLater) {
                                    sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
                                }
                            } else {
                               turnOffUpstreamMobileConnection();
                               Log.d(TAG, "chooseUpstreamType: Reached MAX, NO RETRIES");
                            }
                        } else {
                            Log.d(TAG, "Data is Disabled");
                        }
                    } catch (RemoteException e) {
                        Log.d(TAG, "Exception in getMobileDataEnabled()");
                    }
                } else {
                    LinkProperties linkProperties = null;
                    try {
@@ -1664,6 +1737,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {

                mTryCell = !WAIT_FOR_NETWORK_TO_SETTLE; // better try something first pass
                                                        // or crazy tests cases will fail
                mRetryCount = 0;
                chooseUpstreamType(mTryCell);
                mTryCell = !mTryCell;
            }
@@ -1705,22 +1779,21 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                        }
                        break;
                    case CMD_UPSTREAM_CHANGED:
                        if(VDBG) Log.d(TAG, "CMD_UPSTREAM_CHANGED event received");
                        // need to try DUN immediately if Wifi goes down
                        NetworkInfo info = (NetworkInfo) message.obj;
                        mTryCell = !WAIT_FOR_NETWORK_TO_SETTLE;
                        chooseUpstreamType(mTryCell);
                        if (info != null) {
                            if (!info.isConnected()) {
                        if ((info != null) && (!info.isConnected())) {
                            IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
                            IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
                            try {
                                LinkProperties props = cm.getLinkProperties(info.getType());
                                removeUpstreamV6Interface(props.getInterfaceName());
                                } catch(Exception e) {
                            } catch(RemoteException e) {
                                Log.e(TAG, "Exception querying ConnectivityManager", e);
                            }
                        }
                        }
                        mTryCell = !mTryCell;
                        break;
                    case CMD_CELL_CONNECTION_RENEW:
+25 −10
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {

    INetworkManagementService mNwService;
    private DhcpStateMachine mDhcpStateMachine;
    private ConnectivityManager mCm;

    private P2pStateMachine mP2pStateMachine;
    private AsyncChannel mReplyChannel = new AsyncChannel();
@@ -229,9 +230,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
    /* clients(application) information list. */
    private HashMap<Messenger, ClientInfo> mClientInfoList = new HashMap<Messenger, ClientInfo>();

    /* Is chosen as a unique range to avoid conflict with
       the range defined in Tethering.java */
    private static final String[] DHCP_RANGE = {"192.168.49.2", "192.168.49.254"};
    /* The range defined in Tethering.java include range for P2P group*/
    private static final String SERVER_ADDRESS = "192.168.49.1";

    /**
@@ -2137,16 +2136,29 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    }

    private void checkAndSetConnectivityInstance() {
        if (mCm == null) {
            mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        }
    }

    private void startDhcpServer(String intf) {
        InterfaceConfiguration ifcg = null;

        checkAndSetConnectivityInstance();

        try {
            ifcg = mNwService.getInterfaceConfig(intf);
            if (ifcg != null) {
                ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
                            SERVER_ADDRESS), 24));
                ifcg.setInterfaceUp();
                mNwService.setInterfaceConfig(intf, ifcg);
            /* This starts the dnsmasq server */
            mNwService.startTethering(DHCP_RANGE);
                if (mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
                    loge("Error tethering on " + intf);
                     return;
                }
             }
        } catch (Exception e) {
            loge("Error configuring interface " + intf + ", :" + e);
            return;
@@ -2156,8 +2168,11 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
   }

    private void stopDhcpServer(String intf) {
        checkAndSetConnectivityInstance();
        try {
            mNwService.stopTethering();
            if (mCm.untether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
                loge("Error Untether on " + intf);
            }
        } catch (Exception e) {
            loge("Error stopping Dhcp server" + e);
            return;