[Replicant] [PATCH] Native Android WiFi with external dongle

Belgin ?tirbu belginstirbu at hotmail.com
Fri Aug 30 18:26:58 UTC 2019


This patch allows choosing to use the proprietary firmware blob and
internal WiFi device if the proprietary firmware blob is found.
If proprietary firmware is not found, the patch causes Android's
WiFi State Machine to try to use the external dongle.

The problem with this patch is that Android's WiFi State Machine
tries to enable Bluetooth and IP filters, causing errors in
wpa_supplicant, and after 5 errors, wpa_supplicant thinks
the driver hanged so it disconnects. The workaround to this
is to add a boolean in the WifiStateMachine class that
represents if the connection is via dongle, and avoid
enabling Bluetooth and IP filters in case it is.

This is a workaround because the dongle might actually have
Bluetooth, but I don't know what a proper fix to this would be.

Signed-off-by: belginstirbu <belginstirbu at hotmail.com>
---
 .../com/android/server/wifi/WifiStateMachine.java  | 134 +++++++++++++--------
 1 file changed, 87 insertions(+), 47 deletions(-)

diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 38d0ac8..2acda79 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -198,7 +198,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
     private ConnectivityManager mCm;
     private DummyWifiLogger mWifiLogger;
     private WifiApConfigStore mWifiApConfigStore;
-    private final boolean mP2pSupported;
+    private boolean mP2pSupported;
+    private boolean mDongleConnected;
     private boolean mIbssSupported;
     private final AtomicBoolean mP2pConnected = new AtomicBoolean(false);
     private boolean mTemporarilyDisconnectWifi = false;
@@ -1155,6 +1156,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
         mP2pSupported = mContext.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_WIFI_DIRECT);
 
+	mDongleConnected = false;
+
         mWifiNative = new WifiNative(mInterfaceName);
         mWifiConfigStore = new WifiConfigStore(context,this,  mWifiNative);
         mWifiAutoJoinController = new WifiAutoJoinController(context, this,
@@ -5262,8 +5265,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
 
     private void handleSupplicantConnectionLoss(boolean killSupplicant) {
         /* Socket connection can be lost when we do a graceful shutdown
-        * or when the driver is hung. Ensure supplicant is stopped here.
-        */
+	 * or when the driver is hung. Ensure supplicant is stopped here.
+	 */
         if (killSupplicant) {
             mWifiMonitor.killSupplicant(mP2pSupported);
         }
@@ -5274,27 +5277,31 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
 
     void handlePreDhcpSetup() {
         mDhcpActive = true;
-        // Disable the coexistence mode
-        mWifiNative.setBluetoothCoexistenceMode(
+
+	if(false == mDongleConnected)
+	{
+	    // Disable the coexistence mode
+	    mWifiNative.setBluetoothCoexistenceMode(
                 mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
 
-        // Disable power save and suspend optimizations during DHCP
-        // Note: The order here is important for now. Brcm driver changes
-        // power settings when we control suspend mode optimizations.
-        // TODO: Remove this comment when the driver is fixed.
-        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false);
-        mWifiNative.setPowerSave(false);
+	    // Disable power save and suspend optimizations during DHCP
+	    // Note: The order here is important for now. Brcm driver changes
+	    // power settings when we control suspend mode optimizations.
+	    // TODO: Remove this comment when the driver is fixed.
+	    setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false);
+	    mWifiNative.setPowerSave(false);
+	}
 
-        // Update link layer stats
-        getWifiLinkLayerStats(false);
+	// Update link layer stats
+	getWifiLinkLayerStats(false);
 
-        /* P2p discovery breaks dhcp, shut it down in order to get through this */
-        Message msg = new Message();
-        msg.what = WifiP2pServiceImpl.BLOCK_DISCOVERY;
-        msg.arg1 = WifiP2pServiceImpl.ENABLED;
-        msg.arg2 = DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE;
-        msg.obj = mDhcpStateMachine;
-        mWifiP2pChannel.sendMessage(msg);
+	/* P2p discovery breaks dhcp, shut it down in order to get through this */
+	Message msg = new Message();
+	msg.what = WifiP2pServiceImpl.BLOCK_DISCOVERY;
+	msg.arg1 = WifiP2pServiceImpl.ENABLED;
+	msg.arg2 = DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE;
+	msg.obj = mDhcpStateMachine;
+	mWifiP2pChannel.sendMessage(msg);
     }
 
 
@@ -5337,15 +5344,18 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
     }
 
     void handlePostDhcpSetup() {
-        /* Restore power save and suspend optimizations */
-        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true);
-        mWifiNative.setPowerSave(true);
+	if(false == mDongleConnected)
+	{
+	    /* Restore power save and suspend optimizations */
+	    setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true);
+	    mWifiNative.setPowerSave(true);
 
-        mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.BLOCK_DISCOVERY, WifiP2pServiceImpl.DISABLED);
+	    mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.BLOCK_DISCOVERY, WifiP2pServiceImpl.DISABLED);
 
-        // Set the coexistence mode back to its default value
-        mWifiNative.setBluetoothCoexistenceMode(
+	    // Set the coexistence mode back to its default value
+	    mWifiNative.setBluetoothCoexistenceMode(
                 mWifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
+	}
 
         mDhcpActive = false;
     }
@@ -6047,7 +6057,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
                     * Avoids issues with drivers that do not handle interface down
                     * on a running supplicant properly.
                     */
+
+		    mDongleConnected = false;
+		    
                     mWifiMonitor.killSupplicant(mP2pSupported);
+		    
+		    mP2pSupported = mContext.getPackageManager().hasSystemFeature(
+			PackageManager.FEATURE_WIFI_DIRECT);
 
                     if (mWifiNative.loadDriver()) {
                         try {
@@ -6096,7 +6112,23 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
                         }
                     } else {
                         loge("Failed to load driver");
-                        setWifiState(WifiManager.WIFI_STATE_FAILED);
+
+			loge("Trying to load external wifi dongle");
+
+			mP2pSupported = false;
+			
+			mWifiMonitor.killSupplicant(mP2pSupported);
+			
+                        if (mWifiNative.startSupplicant(mP2pSupported)) {
+                            setWifiState(WIFI_STATE_ENABLING);
+                            if (DBG) log("Supplicant start successful");
+                            mWifiMonitor.startMonitoring();
+			    mDongleConnected = true;
+                            transitionTo(mSupplicantStartingState);
+                        } else {
+                            loge("Failed to start supplicant!");
+                            setWifiState(WifiManager.WIFI_STATE_FAILED);
+                        }
                     }
                     break;
                 case CMD_START_AP:
@@ -6527,24 +6559,28 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
             mInDelayedStop = false;
             mDelayedStopCounter++;
             updateBatteryWorkSource(null);
-            /**
-             * Enable bluetooth coexistence scan mode when bluetooth connection is active.
-             * When this mode is on, some of the low-level scan parameters used by the
-             * driver are changed to reduce interference with bluetooth
-             */
-            mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
-            /* initialize network state */
-            setNetworkDetailedState(DetailedState.DISCONNECTED);
 
-            /* Remove any filtering on Multicast v6 at start */
-            mWifiNative.stopFilteringMulticastV6Packets();
-
-            /* Reset Multicast v4 filtering state */
-            if (mFilteringMulticastV4Packets.get()) {
-                mWifiNative.startFilteringMulticastV4Packets();
-            } else {
-                mWifiNative.stopFilteringMulticastV4Packets();
-            }
+	    if(false == mDongleConnected)
+	    {
+		/**
+		 * Enable bluetooth coexistence scan mode when bluetooth connection is active.
+		 * When this mode is on, some of the low-level scan parameters used by the
+		 * driver are changed to reduce interference with bluetooth
+		 */
+		mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
+		/* initialize network state */
+		setNetworkDetailedState(DetailedState.DISCONNECTED);
+
+		/* Remove any filtering on Multicast v6 at start */
+		mWifiNative.stopFilteringMulticastV6Packets();
+
+		/* Reset Multicast v4 filtering state */
+		if (mFilteringMulticastV4Packets.get()) {
+		    mWifiNative.startFilteringMulticastV4Packets();
+		} else {
+		    mWifiNative.stopFilteringMulticastV4Packets();
+		}
+	    }
 
             mDhcpActive = false;
 
@@ -6647,9 +6683,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
                     }
                     break;
                 case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
-                    mBluetoothConnectionActive = (message.arg1 !=
-                            BluetoothAdapter.STATE_DISCONNECTED);
-                    mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
+		    if(false == mDongleConnected)
+		    {
+			mBluetoothConnectionActive = (message.arg1 !=
+						      BluetoothAdapter.STATE_DISCONNECTED);
+			mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
+		    }
+		    
                     break;
                 case CMD_STOP_DRIVER:
                     int mode = message.arg1;
-- 
2.11.0



More information about the Replicant mailing list