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

Commit fab5c2b2 authored by Vinit Deshapnde's avatar Vinit Deshapnde
Browse files

Synchronize access to single supplicant path

Both wlan0 and p2p0 state machines are accessing the supplicant socket
simultaneously; and may get responses of each other's command. This
change introduces synchronization between these two processes.

Bug: 10375978
Change-Id: I0ac0b2771311b642affc353958cc9ba2e5dd5716
parent 48c47471
Loading
Loading
Loading
Loading
+61 −36
Original line number Diff line number Diff line
@@ -48,6 +48,10 @@ public class WifiNative {
    static final int SCAN_WITHOUT_CONNECTION_SETUP          = 1;
    static final int SCAN_WITH_CONNECTION_SETUP             = 2;

    // Hold this lock before calling supplicant - it is required to
    // mutually exclude access from Wifi and P2p state machines
    static final Object mLock = new Object();

    public final String mInterfaceName;
    public final String mInterfacePrefix;

@@ -92,19 +96,18 @@ public class WifiNative {
        }
    }


    private static final LocalLog mLocalLog = new LocalLog(1024);

    // hold mLock before accessing mCmdIdLock
    private int mCmdId;

    public LocalLog getLocalLog() {
        return mLocalLog;
    }

    private int getNewCmdId() {
        synchronized (mLocalLog) {
    private int getNewCmdIdLocked() {
        return mCmdId++;
    }
    }

    private void localLog(String s) {
        if (mLocalLog != null)
@@ -112,6 +115,7 @@ public class WifiNative {
    }

    public boolean connectToSupplicant() {
        // No synchronization necessary .. it is implemented in WifiMonitor
        localLog(mInterfacePrefix + "connectToSupplicant");
        return connectToSupplicantNative();
    }
@@ -122,40 +126,49 @@ public class WifiNative {
    }

    public String waitForEvent() {
        // No synchronization necessary .. it is implemented in WifiMonitor
        return waitForEventNative();
    }

    private boolean doBooleanCommand(String command) {
        if (DBG) Log.d(mTAG, "doBoolean: " + command);
        int cmdId = getNewCmdId();
        synchronized (mLock) {
            int cmdId = getNewCmdIdLocked();
            localLog(cmdId + "->" + mInterfacePrefix + command);
            boolean result = doBooleanCommandNative(mInterfacePrefix + command);
            localLog(cmdId + "<-" + result);
            return result;
        }
    }

    private int doIntCommand(String command) {
        if (DBG) Log.d(mTAG, "doInt: " + command);
        int cmdId = getNewCmdId();
        synchronized (mLock) {
            int cmdId = getNewCmdIdLocked();
            localLog(cmdId + "->" + mInterfacePrefix + command);
            int result = doIntCommandNative(mInterfacePrefix + command);
            localLog(cmdId + "<-" + result);
            return result;
        }
    }

    private String doStringCommand(String command) {
        if (DBG) Log.d(mTAG, "doString: " + command);
        int cmdId = getNewCmdId();
        synchronized (mLock) {
            int cmdId = getNewCmdIdLocked();
            localLog(cmdId + "->" + mInterfacePrefix + command);
            String result = doStringCommandNative(mInterfacePrefix + command);
            localLog(cmdId + "<-" + result);
            return result;
        }
    }

    private String doStringCommandWithoutLogging(String command) {
        if (DBG) Log.d(mTAG, "doString: " + command);
        synchronized (mLock) {
            return doStringCommandNative(mInterfacePrefix + command);
        }
    }

    public boolean ping() {
        String pong = doStringCommand("PING");
@@ -499,12 +512,14 @@ public class WifiNative {
    }

    public boolean startWpsPbc(String iface, String bssid) {
        synchronized (mLock) {
            if (TextUtils.isEmpty(bssid)) {
                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC");
            } else {
                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC " + bssid);
            }
        }
    }

    public boolean startWpsPinKeypad(String pin) {
        if (TextUtils.isEmpty(pin)) return false;
@@ -513,8 +528,10 @@ public class WifiNative {

    public boolean startWpsPinKeypad(String iface, String pin) {
        if (TextUtils.isEmpty(pin)) return false;
        synchronized (mLock) {
            return doBooleanCommandNative("IFNAME=" + iface + " WPS_PIN any " + pin);
        }
    }


    public String startWpsPinDisplay(String bssid) {
@@ -526,12 +543,14 @@ public class WifiNative {
    }

    public String startWpsPinDisplay(String iface, String bssid) {
        synchronized (mLock) {
            if (TextUtils.isEmpty(bssid)) {
                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN any");
            } else {
                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN " + bssid);
            }
        }
    }

    /* Configures an access point connection */
    public boolean startWpsRegistrar(String bssid, String pin) {
@@ -581,8 +600,10 @@ public class WifiNative {
    }

    public boolean setP2pGroupIdle(String iface, int time) {
        synchronized (mLock) {
            return doBooleanCommandNative("IFNAME=" + iface + " SET p2p_group_idle " + time);
        }
    }

    public void setPowerSave(boolean enabled) {
        if (enabled) {
@@ -593,12 +614,14 @@ public class WifiNative {
    }

    public boolean setP2pPowerSave(String iface, boolean enabled) {
        synchronized (mLock) {
            if (enabled) {
                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 1");
            } else {
                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 0");
            }
        }
    }

    public boolean setWfdEnable(boolean enable) {
        return doBooleanCommand("SET wifi_display " + (enable ? "1" : "0"));
@@ -765,8 +788,10 @@ public class WifiNative {

    public boolean p2pGroupRemove(String iface) {
        if (TextUtils.isEmpty(iface)) return false;
        synchronized (mLock) {
            return doBooleanCommandNative("IFNAME=" + iface + " P2P_GROUP_REMOVE " + iface);
        }
    }

    public boolean p2pReject(String deviceAddress) {
        return doBooleanCommand("P2P_REJECT " + deviceAddress);