diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d435df5..badb767 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -125,13 +125,21 @@
 
     /**
      * @hide
+     * gives a String[]
      */
-    public static final String EXTRA_AVAILABLE_TETHER_COUNT = "availableCount";
+    public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
 
     /**
      * @hide
+     * gives a String[]
      */
-    public static final String EXTRA_ACTIVE_TETHER_COUNT = "activeCount";
+    public static final String EXTRA_ACTIVE_TETHER = "activeArray";
+
+    /**
+     * @hide
+     * gives a String[]
+     */
+    public static final String EXTRA_ERRORED_TETHER = "erroredArray";
 
     /**
      * The Default Mobile data connection.  When active, all data traffic
@@ -400,4 +408,37 @@
             return false;
         }
     }
+
+    /**
+     * {@hide}
+     */
+    public boolean isTetheringSupported() {
+        try {
+            return mService.isTetheringSupported();
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * {@hide}
+     */
+    public String[] getTetherableUsbRegexs() {
+        try {
+            return mService.getTetherableUsbRegexs();
+        } catch (RemoteException e) {
+            return new String[0];
+        }
+    }
+
+    /**
+     * {@hide}
+     */
+    public String[] getTetherableWifiRegexs() {
+        try {
+            return mService.getTetherableWifiRegexs();
+        } catch (RemoteException e) {
+            return new String[0];
+        }
+    }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index caa3f2b..508e9c3a 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -55,7 +55,13 @@
 
     boolean untether(String iface);
 
+    boolean isTetheringSupported();
+
     String[] getTetherableIfaces();
 
     String[] getTetheredIfaces();
+
+    String[] getTetherableUsbRegexs();
+
+    String[] getTetherableWifiRegexs();
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7b52f7f..14e27eb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2210,6 +2210,12 @@
         public static final String NETWORK_PREFERENCE = "network_preference";
 
         /**
+         * Used to disable Tethering on a device - defaults to true
+         * @hide
+         */
+        public static final String TETHER_SUPPORTED = "tether_supported";
+
+        /**
          * No longer supported.
          */
         public static final String PARENTAL_CONTROL_ENABLED = "parental_control_enabled";
diff --git a/core/java/com/android/internal/app/TetherActivity.java b/core/java/com/android/internal/app/TetherActivity.java
index cb268b3..a48ccf9 100644
--- a/core/java/com/android/internal/app/TetherActivity.java
+++ b/core/java/com/android/internal/app/TetherActivity.java
@@ -32,16 +32,19 @@
 import android.util.Log;
 
 /**
- * This activity is shown to the user for him/her to connect/disconnect a Tether
- * connection.  It will display notification when a suitable connection is made
- * to allow the tether to be setup.  A second notification will be show when a
- * tether is active, allowing the user to manage tethered connections.
+ * This activity is shown to the user in two cases: when a connection is possible via
+ * a usb tether and when any type of tether is connected.  In the connecting case
+ * It allows them to start a USB tether.  In the Tethered/disconnecting case it
+ * will disconnect all tethers.
  */
 public class TetherActivity extends AlertActivity implements
         DialogInterface.OnClickListener {
 
     private static final int POSITIVE_BUTTON = AlertDialog.BUTTON1;
 
+    // count of the number of tethered connections at activity create time.
+    private int mTethered;
+
     /* Used to detect when the USB cable is unplugged, so we can call finish() */
     private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
         @Override
@@ -52,8 +55,6 @@
         }
     };
 
-    private boolean mWantTethering;
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -61,17 +62,18 @@
         // determine if we advertise tethering or untethering
         ConnectivityManager cm =
                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
-        if (cm.getTetheredIfaces().length > 0) {
-            mWantTethering = false;
-        } else if (cm.getTetherableIfaces().length > 0) {
-            mWantTethering = true;
-        } else {
+        mTethered = cm.getTetheredIfaces().length;
+        int tetherable = cm.getTetherableIfaces().length;
+        if ((mTethered == 0) && (tetherable == 0)) {
             finish();
             return;
         }
 
-        // Set up the "dialog"
-        if (mWantTethering == true) {
+        // Set up the dialog
+        // if we have a tethered connection we put up a "Do you want to Disconect" dialog
+        // otherwise we must have a tetherable interface (else we'd return above)
+        // and so we want to put up the "do you want to connect" dialog
+        if (mTethered == 0) {
             mAlertParams.mIconId = com.android.internal.R.drawable.ic_dialog_usb;
             mAlertParams.mTitle = getString(com.android.internal.R.string.tether_title);
             mAlertParams.mMessage = getString(com.android.internal.R.string.tether_message);
@@ -114,17 +116,36 @@
      * {@inheritDoc}
      */
     public void onClick(DialogInterface dialog, int which) {
+        boolean error =  false;
 
         if (which == POSITIVE_BUTTON) {
-            ConnectivityManager connManager =
+            ConnectivityManager cm =
                     (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
             // start/stop tethering
-            if (mWantTethering) {
-                if (!connManager.tether("ppp0")) {
+            String[] tethered = cm.getTetheredIfaces();
+
+            if (tethered.length == 0) {
+                String[] tetherable = cm.getTetherableIfaces();
+                String[] usbRegexs = cm.getTetherableUsbRegexs();
+                for (String t : tetherable) {
+                    for (String r : usbRegexs) {
+                        if (t.matches(r)) {
+                            if (!cm.tether(t))
+                                error = true;
+                            break;
+                        }
+                    }
+                }
+                if (error) {
                     showTetheringError();
                 }
             } else {
-                if (!connManager.untether("ppp0")) {
+                for (String t : tethered) {
+                    if (!cm.untether("ppp0")) {
+                        error = true;
+                    }
+                }
+                if (error) {
                     showUnTetheringError();
                 }
             }
@@ -134,7 +155,12 @@
     }
 
     private void handleTetherStateChanged(Intent intent) {
-        finish();
+        // determine if we advertise tethering or untethering
+        ConnectivityManager cm =
+                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+        if (mTethered != cm.getTetheredIfaces().length) {
+            finish();
+        }
     }
 
     private void showTetheringError() {
diff --git a/core/java/com/android/internal/util/HierarchicalStateMachine.java b/core/java/com/android/internal/util/HierarchicalStateMachine.java
index a1c5078..b4af79c 100644
--- a/core/java/com/android/internal/util/HierarchicalStateMachine.java
+++ b/core/java/com/android/internal/util/HierarchicalStateMachine.java
@@ -1021,7 +1021,7 @@
      * @param msg that couldn't be handled.
      */
     protected void unhandledMessage(Message msg) {
-        Log.e(TAG, "unhandledMessage: msg.what=" + msg.what);
+        Log.e(TAG, mName + " - unhandledMessage: msg.what=" + msg.what);
     }
 
     /**
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 40c78f7..5d561b8 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -70,6 +70,22 @@
         <item>"0,1"</item>
     </string-array>
 
+    <!-- List of regexpressions describing the interface (if any) that represent tetherable
+         USB interfaces.  If the device doesn't want to support tething over USB this should
+         be empty.  An example would be "usb.*" -->
+    <string-array translatable="false" name="config_tether_usb_regexs">
+    </string-array>
+
+    <!-- List of regexpressions describing the interface (if any) that represent tetherable
+         Wifi interfaces.  If the device doesn't want to support tethering over Wifi this
+         should be empty.  An example would be "softap.*" -->
+    <string-array translatable="false" name="config_tether_wifi_regexs">
+    </string-array>
+
+    <!-- Dhcp range (min, max) to use for tethering purposes -->
+    <string-array name="config_tether_dhcp_range">
+    </string-array>
+
     <!-- Flag indicating whether the keyguard should be bypassed when
          the slider is open.  This can be set or unset depending how easily
          the slider can be opened (for example, in a pocket or purse). -->
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 4259016..108246d 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -798,6 +798,12 @@
                 "ConnectivityService");
     }
 
+    private void enforceTetherAccessPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.ACCESS_NETWORK_STATE,
+                "ConnectivityService");
+    }
+
     /**
      * Handle a {@code DISCONNECTED} event. If this pertains to the non-active
      * network, we ignore it. If it is for the active network, we send out a
@@ -1289,6 +1295,8 @@
             pw.println(requester.toString());
         }
         pw.println();
+
+        mTethering.dump(fd, pw, args);
     }
 
     // must be stateless - things change under us.
@@ -1386,24 +1394,54 @@
     // javadoc from interface
     public boolean tether(String iface) {
         enforceTetherChangePermission();
-        return mTethering.tether(iface);
+        return isTetheringSupported() && mTethering.tether(iface);
     }
 
     // javadoc from interface
     public boolean untether(String iface) {
         enforceTetherChangePermission();
-        return mTethering.untether(iface);
+        return isTetheringSupported() && mTethering.untether(iface);
+    }
+
+    // TODO - proper iface API for selection by property, inspection, etc
+    public String[] getTetherableUsbRegexs() {
+        enforceTetherAccessPermission();
+        if (isTetheringSupported()) {
+            return mTethering.getTetherableUsbRegexs();
+        } else {
+            return new String[0];
+        }
+    }
+
+    public String[] getTetherableWifiRegexs() {
+        enforceTetherAccessPermission();
+        if (isTetheringSupported()) {
+            return mTethering.getTetherableWifiRegexs();
+        } else {
+            return new String[0];
+        }
     }
 
     // TODO - move iface listing, queries, etc to new module
     // javadoc from interface
     public String[] getTetherableIfaces() {
-        enforceAccessPermission();
+        enforceTetherAccessPermission();
         return mTethering.getTetherableIfaces();
     }
 
     public String[] getTetheredIfaces() {
-        enforceAccessPermission();
+        enforceTetherAccessPermission();
         return mTethering.getTetheredIfaces();
     }
+
+    // if ro.tether.denied = true we default to no tethering
+    // gservices could set the secure setting to 1 though to enable it on a build where it
+    // had previously been turned off.
+    public boolean isTetheringSupported() {
+        enforceTetherAccessPermission();
+        int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
+        return ((Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0) &&
+                (mNetTrackers[ConnectivityManager.TYPE_MOBILE_DUN] != null));
+    }
 }
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index f685383..8d4f244 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -24,19 +24,37 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
+import android.net.NetworkInfo;
+import android.os.Binder;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
+import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.Settings;
 import android.util.Log;
 
+import com.android.internal.telephony.Phone;
+import com.android.internal.util.HierarchicalState;
+import com.android.internal.util.HierarchicalStateMachine;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
 /**
  * @hide
+ *
+ * Timeout
+ * TODO - review error states - they currently are dead-ends with no recovery possible
+ *
+ * TODO - look for parent classes and code sharing
  */
 public class Tethering extends INetworkManagementEventObserver.Stub {
 
@@ -46,13 +64,24 @@
 
     private boolean mPlaySounds = false;
 
-    private ArrayList<String> mAvailableIfaces;
-    private ArrayList<String> mActiveIfaces;
+    // TODO - remove both of these - should be part of interface inspection/selection stuff
+    private String[] mTetherableUsbRegexs;
+    private String[] mTetherableWifiRegexs;
+
+    private HashMap<String, TetherInterfaceSM> mIfaces;
 
     private ArrayList<String> mActiveTtys;
 
     private BroadcastReceiver mStateReceiver;
 
+    private String[] mDhcpRange;
+
+    private String[] mDnsServers;
+
+    private String mUpstreamIfaceName;
+
+    HierarchicalStateMachine mTetherMasterSM;
+
     public Tethering(Context context) {
         Log.d(TAG, "Tethering starting");
         mContext = context;
@@ -66,212 +95,234 @@
             Log.e(TAG, "Error registering observer :" + e);
         }
 
-        mAvailableIfaces = new ArrayList<String>();
-        mActiveIfaces = new ArrayList<String>();
+        mIfaces = new HashMap<String, TetherInterfaceSM>();
         mActiveTtys = new ArrayList<String>();
 
+        mTetherMasterSM = new TetherMasterSM("TetherMaster");
+        mTetherMasterSM.start();
+
         // TODO - remove this hack after real USB connections are detected.
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_UMS_DISCONNECTED);
         filter.addAction(Intent.ACTION_UMS_CONNECTED);
-        mStateReceiver = new UMSStateReceiver();
+        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        mStateReceiver = new StateReceiver();
         mContext.registerReceiver(mStateReceiver, filter);
+
+        mDhcpRange = context.getResources().getStringArray(
+                com.android.internal.R.array.config_tether_dhcp_range);
+        if (mDhcpRange.length == 0) {
+            mDhcpRange = new String[2];
+            mDhcpRange[0] = new String("169.254.2.1");
+            mDhcpRange[1] = new String("169.254.2.64");
+        } else if(mDhcpRange.length == 1) {
+            String[] tmp = new String[2];
+            tmp[0] = mDhcpRange[0];
+            tmp[1] = new String("");
+            mDhcpRange = tmp;
+        }
+
+        mTetherableUsbRegexs = context.getResources().getStringArray(
+                com.android.internal.R.array.config_tether_usb_regexs);
+        mTetherableWifiRegexs = context.getResources().getStringArray(
+                com.android.internal.R.array.config_tether_wifi_regexs);
+
+        String[] ifaces = new String[0];
+        try {
+            ifaces = service.listInterfaces();
+        } catch (Exception e) {
+            Log.e(TAG, "Error listing Interfaces :" + e);
+        }
+        for (String iface : ifaces) {
+            interfaceAdded(iface);
+        }
+
+        // TODO - remove and rely on real notifications of the current iface
+        mDnsServers = new String[2];
+        mDnsServers[0] = "8.8.8.8";
+        mDnsServers[1] = "4.2.2.2";
+        mUpstreamIfaceName = "rmnet0";
     }
 
-    public synchronized void interfaceLinkStatusChanged(String iface, boolean link) {
+    public void interfaceLinkStatusChanged(String iface, boolean link) {
         Log.d(TAG, "interfaceLinkStatusChanged " + iface + ", " + link);
+        boolean found = false;
+        for (String regex : mTetherableWifiRegexs) {
+            if (iface.matches(regex)) {
+                found = true;
+                break;
+            }
+        }
+        for (String regex: mTetherableUsbRegexs) {
+            if (iface.matches(regex)) {
+                found = true;
+                break;
+            }
+        }
+        if (found == false) return;
+
+        synchronized (mIfaces) {
+            TetherInterfaceSM sm = mIfaces.get(iface);
+            if (link) {
+                if (sm == null) {
+                    sm = new TetherInterfaceSM(iface);
+                    mIfaces.put(iface, sm);
+                    sm.start();
+                }
+            } else {
+                if (sm != null) {
+                    sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN));
+                    mIfaces.remove(iface);
+                }
+            }
+        }
     }
 
-    public synchronized void interfaceAdded(String iface) {
-        if (mActiveIfaces.contains(iface)) {
-            Log.e(TAG, "active iface (" + iface + ") reported as added, ignoring");
+    public void interfaceAdded(String iface) {
+        boolean found = false;
+        for (String regex : mTetherableWifiRegexs) {
+            if (iface.matches(regex)) {
+                found = true;
+                break;
+            }
+        }
+        for (String regex : mTetherableUsbRegexs) {
+            if (iface.matches(regex)) {
+                found = true;
+                break;
+            }
+        }
+        if (found == false) {
+            Log.d(TAG, iface + " is not a tetherable iface, ignoring");
             return;
         }
-        if (mAvailableIfaces.contains(iface)) {
-            Log.e(TAG, "available iface (" + iface + ") readded, ignoring");
-            return;
+        synchronized (mIfaces) {
+            TetherInterfaceSM sm = mIfaces.get(iface);
+            if (sm != null) {
+                Log.e(TAG, "active iface (" + iface + ") reported as added, ignoring");
+                return;
+            }
+            sm = new TetherInterfaceSM(iface);
+            mIfaces.put(iface, sm);
+            sm.start();
         }
-        mAvailableIfaces.add(iface);
         Log.d(TAG, "interfaceAdded :" + iface);
-        sendTetherStateChangedBroadcast();
     }
 
-    public synchronized void interfaceRemoved(String iface) {
-        if (mActiveIfaces.contains(iface)) {
-            Log.d(TAG, "removed an active iface (" + iface + ")");
-            untether(iface);
-        }
-        if (mAvailableIfaces.contains(iface)) {
-            mAvailableIfaces.remove(iface);
-            Log.d(TAG, "interfaceRemoved " + iface);
-            sendTetherStateChangedBroadcast();
+    public void interfaceRemoved(String iface) {
+        synchronized (mIfaces) {
+            TetherInterfaceSM sm = mIfaces.get(iface);
+            if (sm == null) {
+                Log.e(TAG, "attempting to remove unknown iface (" + iface + "), ignoring");
+                return;
+            }
+            sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN));
+            mIfaces.remove(iface);
         }
     }
 
-    public synchronized boolean tether(String iface) {
+    public boolean tether(String iface) {
         Log.d(TAG, "Tethering " + iface);
-
-        if (!mAvailableIfaces.contains(iface)) {
+        TetherInterfaceSM sm = null;
+        synchronized (mIfaces) {
+            sm = mIfaces.get(iface);
+        }
+        if (sm == null) {
+            Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring");
+            return false;
+        }
+        if (sm.isErrored()) {
+            Log.e(TAG, "Tried to Tether to an errored iface :" + iface + ", ignoring");
+            return false;
+        }
+        if (!sm.isAvailable()) {
             Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring");
             return false;
         }
-        if (mActiveIfaces.contains(iface)) {
-            Log.e(TAG, "Tried to Tether an already Tethered iface :" + iface + ", ignoring");
-            return false;
-        }
-
-        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
-
-        if (mActiveIfaces.size() == 0) {
-            try {
-                service.setIpForwardingEnabled(true);
-            } catch (Exception e) {
-                Log.e(TAG, "Error in setIpForwardingEnabled(true) :" + e);
-                return false;
-            }
-
-            try {
-                // TODO - don't hardcode this - though with non-conf values (un-routable)
-                // maybe it's not a big deal
-                service.startTethering("169.254.2.1", "169.254.2.64");
-            } catch (Exception e) {
-                Log.e(TAG, "Error in startTethering :" + e);
-                try {
-                    service.setIpForwardingEnabled(false);
-                } catch (Exception ee) {}
-                return false;
-            }
-
-            try {
-                // TODO - maybe use the current connection's dns servers for this
-                String[] dns = new String[2];
-                dns[0] = new String("8.8.8.8");
-                dns[1] = new String("4.2.2.2");
-                service.setDnsForwarders(dns);
-            } catch (Exception e) {
-                Log.e(TAG, "Error in setDnsForwarders :" + e);
-                try {
-                    service.stopTethering();
-                } catch (Exception ee) {}
-                try {
-                    service.setIpForwardingEnabled(false);
-                } catch (Exception ee) {}
-            }
-        }
-
-        try {
-            service.tetherInterface(iface);
-        } catch (Exception e) {
-            Log.e(TAG, "Error in tetherInterface :" + e);
-            if (mActiveIfaces.size() == 0) {
-                try {
-                    service.stopTethering();
-                } catch (Exception ee) {}
-                try {
-                    service.setIpForwardingEnabled(false);
-                } catch (Exception ee) {}
-            }
-            return false;
-        }
-
-        try {
-            // TODO - use the currently active external iface
-            service.enableNat (iface, "rmnet0");
-        } catch (Exception e) {
-            Log.e(TAG, "Error in enableNat :" + e);
-            try {
-                service.untetherInterface(iface);
-            } catch (Exception ee) {}
-            if (mActiveIfaces.size() == 0) {
-                try {
-                    service.stopTethering();
-                } catch (Exception ee) {}
-                try {
-                    service.setIpForwardingEnabled(false);
-                } catch (Exception ee) {}
-            }
-            return false;
-        }
-        mAvailableIfaces.remove(iface);
-        mActiveIfaces.add(iface);
-        Log.d(TAG, "Tethered " + iface);
-        sendTetherStateChangedBroadcast();
+        sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_REQUESTED));
         return true;
     }
 
-    public synchronized boolean untether(String iface) {
+    public boolean untether(String iface) {
         Log.d(TAG, "Untethering " + iface);
-
-        if (mAvailableIfaces.contains(iface)) {
-            Log.e(TAG, "Tried to Untether an available iface :" + iface);
+        TetherInterfaceSM sm = null;
+        synchronized (mIfaces) {
+            sm = mIfaces.get(iface);
+        }
+        if (sm == null) {
+            Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
             return false;
         }
-        if (!mActiveIfaces.contains(iface)) {
-            Log.e(TAG, "Tried to Untether an inactive iface :" + iface);
+        if (sm.isErrored()) {
+            Log.e(TAG, "Tried to Untethered an errored iface :" + iface + ", ignoring");
             return false;
         }
-
-        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
-
-        // none of these errors are recoverable - ie, multiple calls won't help
-        // and the user can't do anything.  Basically a reboot is required and probably
-        // the device is misconfigured or something bad has happend.
-        // Because of this, we should try to unroll as much state as we can.
-        try {
-            service.disableNat(iface, "rmnet0");
-        } catch (Exception e) {
-            Log.e(TAG, "Error in disableNat :" + e);
-        }
-        try {
-            service.untetherInterface(iface);
-        } catch (Exception e) {
-            Log.e(TAG, "Error untethering " + iface + ", :" + e);
-        }
-        mActiveIfaces.remove(iface);
-        mAvailableIfaces.add(iface);
-
-        if (mActiveIfaces.size() == 0) {
-            Log.d(TAG, "no active tethers - turning down dhcp/ipforward");
-            try {
-                service.stopTethering();
-            } catch (Exception e) {
-                Log.e(TAG, "Error in stopTethering :" + e);
-            }
-            try {
-                service.setIpForwardingEnabled(false);
-            } catch (Exception e) {
-                Log.e(TAG, "Error in setIpForwardingEnabled(false) :" + e);
-            }
-        }
-        sendTetherStateChangedBroadcast();
-        Log.d(TAG, "Untethered " + iface);
+        sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_UNREQUESTED));
         return true;
     }
 
     private void sendTetherStateChangedBroadcast() {
+        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+        IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
+        try {
+            if (!service.isTetheringSupported()) return;
+        } catch (RemoteException e) {
+            return;
+        }
+
+        ArrayList<String> availableList = new ArrayList<String>();
+        ArrayList<String> activeList = new ArrayList<String>();
+        ArrayList<String> erroredList = new ArrayList<String>();
+
+        synchronized (mIfaces) {
+            Set ifaces = mIfaces.keySet();
+            for (Object iface : ifaces) {
+                TetherInterfaceSM sm = mIfaces.get(iface);
+                if (sm != null) {
+                    if(sm.isErrored()) {
+                        erroredList.add((String)iface);
+                    } else if (sm.isAvailable()) {
+                        availableList.add((String)iface);
+                    } else if (sm.isTethered()) {
+                        activeList.add((String)iface);
+                    }
+                }
+            }
+        }
         Intent broadcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
         broadcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        broadcast.putExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER_COUNT,
-                mAvailableIfaces.size());
-        broadcast.putExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER_COUNT, mActiveIfaces.size());
-        mContext.sendBroadcast(broadcast);
+        broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER,
+                availableList);
+        broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, activeList);
+        broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER,
+                erroredList);
+        mContext.sendStickyBroadcast(broadcast);
 
-        // for USB we only have the one, so don't have to deal with additional
-        if (mAvailableIfaces.size() > 0) {
-            // Check if the user wants to be bothered
-            boolean tellUser = (Settings.Secure.getInt(mContext.getContentResolver(),
-                    Settings.Secure.TETHER_NOTIFY, 0) == 1);
-
-            if (tellUser) {
-                showTetherAvailableNotification();
+        // check if we need to send a USB notification
+        // Check if the user wants to be bothered
+        boolean tellUser = (Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.TETHER_NOTIFY, 0) == 1);
+        for (Object o : activeList) {
+            String s = (String)o;
+            for (Object regexObject : mTetherableUsbRegexs) {
+                if (s.matches((String)regexObject)) {
+                    showTetheredNotification();
+                    return;
+                }
             }
-        } else if (mActiveIfaces.size() > 0) {
-            showTetheredNotification();
-        } else {
-            clearNotification();
         }
+        if (tellUser) {
+            for (Object o : availableList) {
+                String s = (String)o;
+                for (Object matchObject : mTetherableUsbRegexs) {
+                    if (s.matches((String)matchObject)) {
+                        showTetherAvailableNotification();
+                        return;
+                    }
+                }
+            }
+        }
+        clearNotification();
     }
 
     private void showTetherAvailableNotification() {
@@ -280,7 +331,6 @@
         if (notificationManager == null) {
             return;
         }
-
         Intent intent = new Intent();
         intent.setClass(mContext, com.android.internal.app.TetherActivity.class);
 
@@ -367,18 +417,32 @@
 
 
 
-// TODO - remove this hack after we get proper USB detection
-    private class UMSStateReceiver extends BroadcastReceiver {
+    private class StateReceiver extends BroadcastReceiver {
         public void onReceive(Context content, Intent intent) {
-            if (intent.getAction().equals(Intent.ACTION_UMS_CONNECTED)) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_UMS_CONNECTED)) {
                 Tethering.this.handleTtyConnect();
-            } else if (intent.getAction().equals(Intent.ACTION_UMS_DISCONNECTED)) {
+            } else if (action.equals(Intent.ACTION_UMS_DISCONNECTED)) {
                 Tethering.this.handleTtyDisconnect();
+            } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+                IConnectivityManager service =
+                        IConnectivityManager.Stub.asInterface(b);
+                try {
+                    NetworkInfo info = service.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_DUN);
+                    int msg;
+                    if (info.isConnected() == true) {
+                        msg = TetherMasterSM.CMD_CELL_DUN_ENABLED;
+                    } else {
+                        msg = TetherMasterSM.CMD_CELL_DUN_DISABLED;
+                    }
+                    mTetherMasterSM.sendMessage(mTetherMasterSM.obtainMessage(msg));
+                } catch (RemoteException e) {}
             }
         }
     }
 
-    private synchronized void handleTtyConnect() {
+    private void handleTtyConnect() {
         Log.d(TAG, "handleTtyConnect");
         // for each of the available Tty not already supported by a ppp session,
         // create a ppp session
@@ -461,23 +525,950 @@
         }
     }
 
-    public synchronized String[] getTetheredIfaces() {
-        int size = mActiveIfaces.size();
-        String[] result = new String[size];
-        size -= 1;
-        for (int i=0; i< size; i++) {
-            result[i] = mActiveIfaces.get(i);
-        }
-        return result;
+    public String[] getTetherableUsbRegexs() {
+        return mTetherableUsbRegexs;
     }
 
-    public synchronized String[] getTetherableIfaces() {
-        int size = mAvailableIfaces.size();
-        String[] result = new String[size];
-        size -= 1;
-        for (int i=0; i< size; i++) {
-            result[i] = mActiveIfaces.get(i);
+    public String[] getTetherableWifiRegexs() {
+        return mTetherableWifiRegexs;
+    }
+
+    public String[] getTetheredIfaces() {
+        ArrayList<String> list = new ArrayList<String>();
+        synchronized (mIfaces) {
+            Set keys = mIfaces.keySet();
+            for (Object key : keys) {
+                TetherInterfaceSM sm = mIfaces.get(key);
+                if (sm.isTethered()) {
+                    list.add((String)key);
+                }
+            }
         }
-        return result;
+        String[] retVal = new String[list.size()];
+        for (int i=0; i < list.size(); i++) {
+            retVal[i] = list.get(i);
+        }
+        return retVal;
+    }
+
+    public String[] getTetherableIfaces() {
+        ArrayList<String> list = new ArrayList<String>();
+        synchronized (mIfaces) {
+            Set keys = mIfaces.keySet();
+            for (Object key : keys) {
+                TetherInterfaceSM sm = mIfaces.get(key);
+                if (sm.isAvailable()) {
+                    list.add((String)key);
+                }
+            }
+        }
+        String[] retVal = new String[list.size()];
+        for (int i=0; i < list.size(); i++) {
+            retVal[i] = list.get(i);
+        }
+        return retVal;
+    }
+
+
+    class TetherInterfaceSM extends HierarchicalStateMachine {
+        // notification from the master SM that it's in tether mode
+        static final int CMD_TETHER_MODE_ALIVE           =  1;
+        // notification from the master SM that it's not in tether mode
+        static final int CMD_TETHER_MODE_DEAD            =  2;
+        // request from the user that it wants to tether
+        static final int CMD_TETHER_REQUESTED            =  3;
+        // request from the user that it wants to untether
+        static final int CMD_TETHER_UNREQUESTED          =  4;
+        // notification that this interface is down
+        static final int CMD_INTERFACE_DOWN              =  5;
+        // notification that this interface is up
+        static final int CMD_INTERFACE_UP                =  6;
+        // notification from the master SM that it had an error turning on cellular dun
+        static final int CMD_CELL_DUN_ERROR              = 10;
+        // notification from the master SM that it had trouble enabling IP Forwarding
+        static final int CMD_IP_FORWARDING_ENABLE_ERROR  = 11;
+        // notification from the master SM that it had trouble disabling IP Forwarding
+        static final int CMD_IP_FORWARDING_DISABLE_ERROR = 12;
+        // notification from the master SM that it had trouble staring tethering
+        static final int CMD_START_TETHERING_ERROR       = 13;
+        // notification from the master SM that it had trouble stopping tethering
+        static final int CMD_STOP_TETHERING_ERROR        = 14;
+        // notification from the master SM that it had trouble setting the DNS forwarders
+        static final int CMD_SET_DNS_FORWARDERS_ERROR    = 15;
+        // a mechanism to transition self to error state from an enter function
+        static final int CMD_TRANSITION_TO_ERROR         = 16;
+
+        private HierarchicalState mDefaultState;
+
+        private HierarchicalState mInitialState;
+        private HierarchicalState mStartingState;
+        private HierarchicalState mTetheredState;
+
+        private HierarchicalState mMasterTetherErrorState;
+        private HierarchicalState mTetherInterfaceErrorState;
+        private HierarchicalState mUntetherInterfaceErrorState;
+        private HierarchicalState mEnableNatErrorState;
+        private HierarchicalState mDisableNatErrorState;
+
+        private HierarchicalState mUnavailableState;
+
+        private boolean mAvailable;
+        private boolean mErrored;
+        private boolean mTethered;
+
+        String mIfaceName;
+
+        TetherInterfaceSM(String name) {
+            super(name);
+            mIfaceName = name;
+
+            mInitialState = new InitialState();
+            addState(mInitialState);
+            mStartingState = new StartingState();
+            addState(mStartingState);
+            mTetheredState = new TetheredState();
+            addState(mTetheredState);
+            mMasterTetherErrorState = new MasterTetherErrorState();
+            addState(mMasterTetherErrorState);
+            mTetherInterfaceErrorState = new TetherInterfaceErrorState();
+            addState(mTetherInterfaceErrorState);
+            mUntetherInterfaceErrorState = new UntetherInterfaceErrorState();
+            addState(mUntetherInterfaceErrorState);
+            mEnableNatErrorState = new EnableNatErrorState();
+            addState(mEnableNatErrorState);
+            mDisableNatErrorState = new DisableNatErrorState();
+            addState(mDisableNatErrorState);
+            mUnavailableState = new UnavailableState();
+            addState(mUnavailableState);
+
+            setInitialState(mInitialState);
+        }
+
+        public String toString() {
+            String res = new String();
+            res += mIfaceName + " - ";
+            HierarchicalState current = getCurrentState();
+            if (current == mInitialState) res += "InitialState";
+            if (current == mStartingState) res += "StartingState";
+            if (current == mTetheredState) res += "TetheredState";
+            if (current == mMasterTetherErrorState) res += "MasterTetherErrorState";
+            if (current == mTetherInterfaceErrorState) res += "TetherInterfaceErrorState";
+            if (current == mUntetherInterfaceErrorState) res += "UntetherInterfaceErrorState";
+            if (current == mEnableNatErrorState) res += "EnableNatErrorState";
+            if (current == mDisableNatErrorState) res += "DisableNatErrorState";
+            if (current == mUnavailableState) res += "UnavailableState";
+            if (mAvailable) res += " - Available";
+            if (mTethered) res += " - Tethered";
+            if (mErrored) res += " - ERRORED";
+            return res;
+        }
+
+        // synchronized between this getter and the following setter
+        public synchronized boolean isAvailable() {
+            return mAvailable;
+        }
+
+        private synchronized void setAvailable(boolean available) {
+            mAvailable = available;
+        }
+
+        // synchronized between this getter and the following setter
+        public synchronized boolean isTethered() {
+            return mTethered;
+        }
+
+        private synchronized void setTethered(boolean tethered) {
+            mTethered = tethered;
+        }
+
+        // synchronized between this getter and the following setter
+        public synchronized boolean isErrored() {
+            return mErrored;
+        }
+
+        private synchronized void setErrored(boolean errored) {
+            mErrored = errored;
+        }
+
+        class InitialState extends HierarchicalState {
+            @Override
+            public void enter() {
+                setAvailable(true);
+                setTethered(false);
+                setErrored(false);
+                sendTetherStateChangedBroadcast();
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(TAG, "InitialState.processMessage what=" + message.what);
+                boolean retValue = true;
+                switch (message.what) {
+                    case CMD_TETHER_REQUESTED:
+                        Message m = mTetherMasterSM.obtainMessage(
+                                TetherMasterSM.CMD_TETHER_MODE_REQUESTED);
+                        m.obj = TetherInterfaceSM.this;
+                        mTetherMasterSM.sendMessage(m);
+                        transitionTo(mStartingState);
+                        break;
+                    case CMD_INTERFACE_DOWN:
+                        transitionTo(mUnavailableState);
+                        break;
+                    default:
+                        retValue = false;
+                        break;
+                }
+                return retValue;
+            }
+        }
+
+        class StartingState extends HierarchicalState {
+            @Override
+            public void enter() {
+                setAvailable(false);
+                sendTetherStateChangedBroadcast();
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(TAG, "StartingState.processMessage what=" + message.what);
+                boolean retValue = true;
+                switch (message.what) {
+                    // maybe a parent class?
+                    case CMD_TETHER_UNREQUESTED:
+                        Message m = mTetherMasterSM.obtainMessage(
+                                TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED);
+                        m.obj = TetherInterfaceSM.this;
+                        mTetherMasterSM.sendMessage(m);
+                        transitionTo(mInitialState);
+                        break;
+                    case CMD_TETHER_MODE_ALIVE:
+                        transitionTo(mTetheredState);
+                        break;
+                    case CMD_CELL_DUN_ERROR:
+                    case CMD_IP_FORWARDING_ENABLE_ERROR:
+                    case CMD_IP_FORWARDING_DISABLE_ERROR:
+                    case CMD_START_TETHERING_ERROR:
+                    case CMD_STOP_TETHERING_ERROR:
+                    case CMD_SET_DNS_FORWARDERS_ERROR:
+                        transitionTo(mMasterTetherErrorState);
+                        break;
+                    case CMD_INTERFACE_DOWN:
+                        m = mTetherMasterSM.obtainMessage(
+                                TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED);
+                        m.obj = TetherInterfaceSM.this;
+                        mTetherMasterSM.sendMessage(m);
+                        transitionTo(mUnavailableState);
+                        break;
+                    default:
+                        retValue = false;
+                }
+                return retValue;
+            }
+        }
+
+        class TetheredState extends HierarchicalState {
+            @Override
+            public void enter() {
+                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                INetworkManagementService service =
+                        INetworkManagementService.Stub.asInterface(b);
+                try {
+                    service.tetherInterface(mIfaceName);
+                } catch (Exception e) {
+                    Message m = obtainMessage(CMD_TRANSITION_TO_ERROR);
+                    m.obj = mTetherInterfaceErrorState;
+                    sendMessageAtFrontOfQueue(m);
+                    return;
+                }
+                try {
+                    service.enableNat(mIfaceName, mUpstreamIfaceName);
+                } catch (Exception e) {
+                    Message m = obtainMessage(CMD_TRANSITION_TO_ERROR);
+                    m.obj = mEnableNatErrorState;
+                    sendMessageAtFrontOfQueue(m);
+                    return;
+                }
+                Log.d(TAG, "Tethered " + mIfaceName);
+                setAvailable(false);
+                setTethered(true);
+                sendTetherStateChangedBroadcast();
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(TAG, "TetheredState.processMessage what=" + message.what);
+                boolean retValue = true;
+                boolean error = false;
+                switch (message.what) {
+                    case CMD_TETHER_UNREQUESTED:
+                    case CMD_INTERFACE_DOWN:
+                        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                        INetworkManagementService service =
+                                INetworkManagementService.Stub.asInterface(b);
+                        try {
+                            service.disableNat(mIfaceName, mUpstreamIfaceName);
+                        } catch (Exception e) {
+                            transitionTo(mDisableNatErrorState);
+                            break;
+                        }
+                        try {
+                            service.untetherInterface(mIfaceName);
+                        } catch (Exception e) {
+                            transitionTo(mUntetherInterfaceErrorState);
+                            break;
+                        }
+                        Message m = mTetherMasterSM.obtainMessage(
+                                TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED);
+                        m.obj = TetherInterfaceSM.this;
+                        mTetherMasterSM.sendMessage(m);
+                        if (message.what == CMD_TETHER_UNREQUESTED) {
+                            transitionTo(mInitialState);
+                        } else if (message.what == CMD_INTERFACE_DOWN) {
+                            transitionTo(mUnavailableState);
+                        }
+                        Log.d(TAG, "Untethered " + mIfaceName);
+                        sendTetherStateChangedBroadcast();
+                        break;
+                    case CMD_CELL_DUN_ERROR:
+                    case CMD_IP_FORWARDING_ENABLE_ERROR:
+                    case CMD_IP_FORWARDING_DISABLE_ERROR:
+                    case CMD_START_TETHERING_ERROR:
+                    case CMD_STOP_TETHERING_ERROR:
+                    case CMD_SET_DNS_FORWARDERS_ERROR:
+                        error = true;
+                        // fall through
+                    case CMD_TETHER_MODE_DEAD:
+                        b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                        service = INetworkManagementService.Stub.asInterface(b);
+                        try {
+                            service.disableNat(mIfaceName, mUpstreamIfaceName);
+                        } catch (Exception e) {
+                            transitionTo(mDisableNatErrorState);
+                            break;
+                        }
+                        try {
+                            service.untetherInterface(mIfaceName);
+                        } catch (Exception e) {
+                            transitionTo(mUntetherInterfaceErrorState);
+                            break;
+                        }
+                        if (error) {
+                            transitionTo(mMasterTetherErrorState);
+                            break;
+                        }
+                        Log.d(TAG, "Tether lost upstream connection " + mIfaceName);
+                        sendTetherStateChangedBroadcast();
+                        transitionTo(mInitialState);
+                        break;
+                    case CMD_TRANSITION_TO_ERROR:
+                        HierarchicalState s = (HierarchicalState)(message.obj);
+                        transitionTo(s);
+                        break;
+                    default:
+                        retValue = false;
+                        break;
+                }
+                return retValue;
+            }
+        }
+
+        class UnavailableState extends HierarchicalState {
+            @Override
+            public void enter() {
+                setAvailable(false);
+                setErrored(false);
+                setTethered(false);
+                sendTetherStateChangedBroadcast();
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                boolean retValue = true;
+                switch (message.what) {
+                    case CMD_INTERFACE_UP:
+                        transitionTo(mInitialState);
+                        break;
+                    default:
+                        retValue = false;
+                        break;
+                }
+                return retValue;
+            }
+        }
+
+
+        class ErrorState extends HierarchicalState {
+            int mErrorNotification;
+            @Override
+            public boolean processMessage(Message message) {
+                boolean retValue = true;
+                switch (message.what) {
+                    case CMD_TETHER_REQUESTED:
+                        sendTetherStateChangedBroadcast();
+                        break;
+                    default:
+                        retValue = false;
+                        break;
+                }
+                return retValue;
+            }
+        }
+
+        class MasterTetherErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error in Master Tether state " + mIfaceName);
+                setAvailable(false);
+                setErrored(true);
+                sendTetherStateChangedBroadcast();
+            }
+        }
+
+        class TetherInterfaceErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error trying to tether " + mIfaceName);
+                setAvailable(false);
+                setErrored(true);
+                sendTetherStateChangedBroadcast();
+            }
+        }
+
+        class UntetherInterfaceErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error trying to untether " + mIfaceName);
+                setAvailable(false);
+                setErrored(true);
+                sendTetherStateChangedBroadcast();
+            }
+        }
+
+        class EnableNatErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error trying to enable NAT " + mIfaceName);
+                setAvailable(false);
+                setErrored(true);
+
+                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
+                try {
+                    service.untetherInterface(mIfaceName);
+                } catch (Exception e) {}
+                sendTetherStateChangedBroadcast();
+            }
+        }
+
+
+        class DisableNatErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error trying to disable NAT " + mIfaceName);
+                setAvailable(false);
+                setErrored(true);
+
+                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
+                try {
+                    service.untetherInterface(mIfaceName);
+                } catch (Exception e) {}
+                sendTetherStateChangedBroadcast();
+            }
+        }
+    }
+
+    class TetherMasterSM extends HierarchicalStateMachine {
+        // an interface SM has requested Tethering
+        static final int CMD_TETHER_MODE_REQUESTED   = 1;
+        // an interface SM has unrequested Tethering
+        static final int CMD_TETHER_MODE_UNREQUESTED = 2;
+        // we received notice that the cellular DUN connection is up
+        static final int CMD_CELL_DUN_ENABLED        = 3;
+        // we received notice that the cellular DUN connection is down
+        static final int CMD_CELL_DUN_DISABLED       = 4;
+        // we timed out on a cellular DUN toggle
+        static final int CMD_CELL_DUN_TIMEOUT        = 5;
+        // it's time to renew our cellular DUN reservation
+        static final int CMD_CELL_DUN_RENEW          = 6;
+
+        // This indicates what a timeout event relates to.  A state that
+        // sends itself a delayed timeout event and handles incoming timeout events
+        // should inc this when it is entered and whenever it sends a new timeout event.
+        // We do not flush the old ones.
+        private int mSequenceNumber;
+
+        private HierarchicalState mInitialState;
+        private HierarchicalState mCellDunRequestedState;
+        private HierarchicalState mCellDunAliveState;
+        private HierarchicalState mTetherModeAliveState;
+        private HierarchicalState mCellDunUnRequestedState;
+
+        private HierarchicalState mCellDunErrorState;
+        private HierarchicalState mSetIpForwardingEnabledErrorState;
+        private HierarchicalState mSetIpForwardingDisabledErrorState;
+        private HierarchicalState mStartTetheringErrorState;
+        private HierarchicalState mStopTetheringErrorState;
+        private HierarchicalState mSetDnsForwardersErrorState;
+
+        private ArrayList mNotifyList;
+
+
+        private static final int CELL_DUN_TIMEOUT_MS         = 45000;
+        private static final int CELL_DISABLE_DUN_TIMEOUT_MS = 3000;
+        private static final int CELL_DUN_RENEW_MS           = 40000;
+
+        TetherMasterSM(String name) {
+            super(name);
+
+            //Add states
+            mInitialState = new InitialState();
+            addState(mInitialState);
+            mCellDunRequestedState = new CellDunRequestedState();
+            addState(mCellDunRequestedState);
+            mCellDunAliveState = new CellDunAliveState();
+            addState(mCellDunAliveState);
+            mTetherModeAliveState = new TetherModeAliveState();
+            addState(mTetherModeAliveState);
+            mCellDunUnRequestedState = new CellDunUnRequestedState();
+            addState(mCellDunUnRequestedState);
+
+            mCellDunErrorState = new CellDunErrorState();
+            addState(mCellDunErrorState);
+            mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
+            addState(mSetIpForwardingEnabledErrorState);
+            mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
+            addState(mSetIpForwardingDisabledErrorState);
+            mStartTetheringErrorState = new StartTetheringErrorState();
+            addState(mStartTetheringErrorState);
+            mStopTetheringErrorState = new StopTetheringErrorState();
+            addState(mStopTetheringErrorState);
+            mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
+            addState(mSetDnsForwardersErrorState);
+
+            mNotifyList = new ArrayList();
+
+            setInitialState(mInitialState);
+        }
+
+
+        class InitialState extends HierarchicalState {
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(TAG, "MasterInitialState.processMessage what=" + message.what);
+                boolean retValue = true;
+                switch (message.what) {
+                    case CMD_TETHER_MODE_REQUESTED:
+                        TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+                        Log.d(TAG, "Tether Mode requested by " + who.toString());
+                        mNotifyList.add(who);
+                        transitionTo(mCellDunRequestedState);
+                        break;
+                    case CMD_TETHER_MODE_UNREQUESTED:
+                        who = (TetherInterfaceSM)message.obj;
+                        Log.d(TAG, "Tether Mode unrequested by " + who.toString());
+                        int index = mNotifyList.indexOf(who);
+                        if (index != -1) {
+                            mNotifyList.remove(who);
+                        }
+                        break;
+                    case CMD_CELL_DUN_ENABLED:
+                        transitionTo(mCellDunAliveState);
+                        break;
+                    default:
+                        retValue = false;
+                        break;
+                }
+                return retValue;
+            }
+        }
+        class CellDunRequestedState extends HierarchicalState {
+            @Override
+            public void enter() {
+                ++mSequenceNumber;
+                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+                IConnectivityManager service =
+                        IConnectivityManager.Stub.asInterface(b);
+                int result;
+                try {
+                    result = service.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                            Phone.FEATURE_ENABLE_DUN, new Binder());
+                } catch (Exception e) {
+                    result = Phone.APN_REQUEST_FAILED;
+                }
+                switch (result) {
+                    case Phone.APN_ALREADY_ACTIVE:
+                        Log.d(TAG, "Dun already active");
+                        sendMessage(obtainMessage(CMD_CELL_DUN_ENABLED));
+                        break;
+                    case Phone.APN_REQUEST_FAILED:
+                    case Phone.APN_TYPE_NOT_AVAILABLE:
+                        Log.d(TAG, "Error bringing up Dun connection");
+                        Message m = obtainMessage(CMD_CELL_DUN_TIMEOUT);
+                        m.arg1 = mSequenceNumber;
+                        sendMessage(m);
+                        break;
+                    case Phone.APN_REQUEST_STARTED:
+                        Log.d(TAG, "Started bringing up Dun connection");
+                        m = obtainMessage(CMD_CELL_DUN_TIMEOUT);
+                        m.arg1 = mSequenceNumber;
+                        sendMessageDelayed(m, CELL_DUN_TIMEOUT_MS);
+                        break;
+                    default:
+                        Log.e(TAG, "Unknown return value from startUsingNetworkFeature " + result);
+                }
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(TAG, "CellDunRequestedState.processMessage what=" + message.what);
+                boolean retValue = true;
+                switch (message.what) {
+                    case CMD_TETHER_MODE_REQUESTED:
+                        TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+                        mNotifyList.add(who);
+                        break;
+                    case CMD_TETHER_MODE_UNREQUESTED:
+                        who = (TetherInterfaceSM)message.obj;
+                        int index = mNotifyList.indexOf(who);
+                        if (index != -1) {
+                            mNotifyList.remove(index);
+                            if (mNotifyList.isEmpty()) {
+                                transitionTo(mCellDunUnRequestedState);
+                            }
+                        }
+                        break;
+                    case CMD_CELL_DUN_ENABLED:
+                        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                        INetworkManagementService service =
+                                INetworkManagementService.Stub.asInterface(b);
+
+                        try {
+                            service.setIpForwardingEnabled(true);
+                        } catch (Exception e) {
+                            transitionTo(mSetIpForwardingEnabledErrorState);
+                            break;
+                        }
+                        try {
+                            service.startTethering(mDhcpRange[0], mDhcpRange[1]);
+                        } catch (Exception e) {
+                            transitionTo(mStartTetheringErrorState);
+                            break;
+                        }
+                        try {
+                            service.setDnsForwarders(mDnsServers);
+                        } catch (Exception e) {
+                            transitionTo(mSetDnsForwardersErrorState);
+                            break;
+                        }
+                        transitionTo(mTetherModeAliveState);
+                        break;
+                    case CMD_CELL_DUN_DISABLED:
+                        break;
+                    case CMD_CELL_DUN_TIMEOUT:
+                        if (message.arg1 == mSequenceNumber) {
+                            transitionTo(mCellDunErrorState);
+                        }
+                        break;
+                    default:
+                        retValue = false;
+                        break;
+                }
+                return retValue;
+            }
+        }
+
+        class CellDunAliveState extends HierarchicalState {
+            @Override
+            public void enter() {
+                sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS);
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(TAG, "CellDunAliveState.processMessage what=" + message.what);
+                boolean retValue = true;
+                switch (message.what) {
+                    case CMD_TETHER_MODE_REQUESTED:
+                        TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+                        mNotifyList.add(who);
+                        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                        INetworkManagementService service =
+                                INetworkManagementService.Stub.asInterface(b);
+
+                        try {
+                            service.setIpForwardingEnabled(true);
+                        } catch (Exception e) {
+                            transitionTo(mSetIpForwardingEnabledErrorState);
+                            break;
+                        }
+                        try {
+                            service.startTethering(mDhcpRange[0], mDhcpRange[1]);
+                        } catch (Exception e) {
+                            transitionTo(mStartTetheringErrorState);
+                            break;
+                        }
+                        try {
+                            service.setDnsForwarders(mDnsServers);
+                        } catch (Exception e) {
+                            transitionTo(mSetDnsForwardersErrorState);
+                            break;
+                        }
+                        transitionTo(mTetherModeAliveState);
+                        break;
+                    case CMD_TETHER_MODE_UNREQUESTED:
+                        who = (TetherInterfaceSM)message.obj;
+                        int index = mNotifyList.indexOf(who);
+                        if (index != -1) {
+                            mNotifyList.remove(index);
+                            if (mNotifyList.isEmpty()) {
+                                transitionTo(mCellDunUnRequestedState);
+                            }
+                        }
+                        break;
+                    case CMD_CELL_DUN_DISABLED:
+                        transitionTo(mInitialState);
+                        break;
+                    case CMD_CELL_DUN_RENEW:
+                        b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+                        IConnectivityManager cservice = IConnectivityManager.Stub.asInterface(b);
+                        try {
+                            cservice.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                                    Phone.FEATURE_ENABLE_DUN, new Binder());
+                        } catch (Exception e) {
+                        }
+                        sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS);
+                        break;
+                    default:
+                        retValue = false;
+                        break;
+                }
+                return retValue;
+            }
+        }
+
+        class TetherModeAliveState extends HierarchicalState {
+            @Override
+            public void enter() {
+                for (Object o : mNotifyList) {
+                    TetherInterfaceSM sm = (TetherInterfaceSM)o;
+                    sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_MODE_ALIVE));
+                }
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(TAG, "TetherModeAliveState.processMessage what=" + message.what);
+                boolean retValue = true;
+                switch (message.what) {
+                    case CMD_TETHER_MODE_REQUESTED:
+                        TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+                        mNotifyList.add(who);
+                        who.sendMessage(who.obtainMessage(TetherInterfaceSM.CMD_TETHER_MODE_ALIVE));
+                        break;
+                    case CMD_TETHER_MODE_UNREQUESTED:
+                        who = (TetherInterfaceSM)message.obj;
+                        int index = mNotifyList.indexOf(who);
+                        if (index != -1) {
+                            mNotifyList.remove(index);
+                            if (mNotifyList.isEmpty()) {
+                                transitionTo(mCellDunUnRequestedState);
+                            }
+                        }
+                        break;
+                    case CMD_CELL_DUN_DISABLED:
+                        int size = mNotifyList.size();
+                        for (int i = 0; i < size; i++) {
+                            TetherInterfaceSM sm = (TetherInterfaceSM)mNotifyList.get(i);
+                            mNotifyList.remove(i);
+                            sm.sendMessage(sm.obtainMessage(
+                                    TetherInterfaceSM.CMD_TETHER_MODE_DEAD));
+                        }
+                        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                        INetworkManagementService service =
+                                INetworkManagementService.Stub.asInterface(b);
+                        try {
+                            service.stopTethering();
+                        } catch (Exception e) {
+                            transitionTo(mStopTetheringErrorState);
+                            break;
+                        }
+                        try {
+                            service.setIpForwardingEnabled(false);
+                        } catch (Exception e) {
+                            transitionTo(mSetIpForwardingDisabledErrorState);
+                            break;
+                        }
+                        transitionTo(mInitialState);
+                        break;
+                    default:
+                       retValue = false;
+                       break;
+                }
+                return retValue;
+            }
+        }
+
+        class CellDunUnRequestedState extends HierarchicalState {
+            @Override
+            public void enter() {
+                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+                IConnectivityManager service =
+                        IConnectivityManager.Stub.asInterface(b);
+                NetworkInfo dunInfo = null;
+                try {
+                    dunInfo = service.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_DUN);
+                } catch (Exception e) {}
+                if (dunInfo != null && !dunInfo.isConnectedOrConnecting()) {
+                    sendMessage(obtainMessage(CMD_CELL_DUN_DISABLED));
+                    return;
+                }
+                try {
+                    service.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                            Phone.FEATURE_ENABLE_DUN);
+                } catch (Exception e) {}
+                Message m =  obtainMessage(CMD_CELL_DUN_TIMEOUT);
+                m.arg1 = ++mSequenceNumber;
+                // use a short timeout - this will often be a no-op and
+                // we just want this request to get into the queue before we
+                // try again.
+                sendMessageDelayed(m, CELL_DISABLE_DUN_TIMEOUT_MS);
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(TAG, "CellDunUnRequestedState.processMessage what=" + message.what);
+                boolean retValue = true;
+                switch (message.what) {
+                    case CMD_TETHER_MODE_REQUESTED:
+                    case CMD_TETHER_MODE_UNREQUESTED:
+                        deferMessage(message);
+                        break;
+                    case CMD_CELL_DUN_DISABLED:
+                        transitionTo(mInitialState);
+                        break;
+                    case CMD_CELL_DUN_TIMEOUT:
+                        // if we aren't using a sep apn, we won't get a disconnect broadcast..
+                        // just go back to initial after our short pause
+                        if (message.arg1 == mSequenceNumber) {
+                            transitionTo(mInitialState);
+                        }
+                        break;
+                    default:
+                        retValue = false;
+                        break;
+                }
+                return retValue;
+            }
+        }
+
+        class ErrorState extends HierarchicalState {
+            int mErrorNotification;
+            @Override
+            public boolean processMessage(Message message) {
+                boolean retValue = true;
+                switch (message.what) {
+                    case CMD_TETHER_MODE_REQUESTED:
+                        TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+                        who.sendMessage(who.obtainMessage(mErrorNotification));
+                        break;
+                    default:
+                       retValue = false;
+                }
+                return retValue;
+            }
+            void notify(int msgType) {
+                mErrorNotification = msgType;
+                for (Object o : mNotifyList) {
+                    TetherInterfaceSM sm = (TetherInterfaceSM)o;
+                    sm.sendMessage(sm.obtainMessage(msgType));
+                }
+            }
+
+        }
+        class CellDunErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error trying to enable Cell DUN");
+                notify(TetherInterfaceSM.CMD_CELL_DUN_ERROR);
+            }
+        }
+
+        class SetIpForwardingEnabledErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error in setIpForwardingEnabled");
+                notify(TetherInterfaceSM.CMD_IP_FORWARDING_ENABLE_ERROR);
+            }
+        }
+
+        class SetIpForwardingDisabledErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error in setIpForwardingDisabled");
+                notify(TetherInterfaceSM.CMD_IP_FORWARDING_DISABLE_ERROR);
+            }
+        }
+
+        class StartTetheringErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error in startTethering");
+                notify(TetherInterfaceSM.CMD_START_TETHERING_ERROR);
+                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                INetworkManagementService service =
+                        INetworkManagementService.Stub.asInterface(b);
+                try {
+                    service.setIpForwardingEnabled(false);
+                } catch (Exception e) {}
+            }
+        }
+
+        class StopTetheringErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error in stopTethering");
+                notify(TetherInterfaceSM.CMD_STOP_TETHERING_ERROR);
+                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                INetworkManagementService service =
+                         INetworkManagementService.Stub.asInterface(b);
+                try {
+                    service.setIpForwardingEnabled(false);
+                } catch (Exception e) {}
+            }
+        }
+
+        class SetDnsForwardersErrorState extends ErrorState {
+            @Override
+            public void enter() {
+                Log.e(TAG, "Error in setDnsForwarders");
+                notify(TetherInterfaceSM.CMD_SET_DNS_FORWARDERS_ERROR);
+                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                INetworkManagementService service =
+                        INetworkManagementService.Stub.asInterface(b);
+                try {
+                    service.stopTethering();
+                } catch (Exception e) {}
+                try {
+                    service.setIpForwardingEnabled(false);
+                } catch (Exception e) {}
+            }
+        }
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(
+                android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump ConnectivityService.Tether " +
+                    "from from pid=" + Binder.getCallingPid() + ", uid=" +
+                    Binder.getCallingUid());
+                    return;
+        }
+
+        pw.println();
+        pw.println("Tether state:");
+        synchronized (mIfaces) {
+            for (Object o : mIfaces.values()) {
+                pw.println(" "+o.toString());
+            }
+        }
+        pw.println();
+        return;
     }
 }
