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

Commit 64f0d5ba authored by Vinit Deshapnde's avatar Vinit Deshapnde
Browse files

Allow enabling TDLS on specific routes

This change exposes couple of internal APIs to enable TDLS between local
machine and a remote machine. The implementation translates client provided
remote IP to a MAC address using system ARP cache, and then instructs the
driver to enable TDLS with that endpoint. Another API takes application
specified MAC address.

Bug: 8538898

Change-Id: Ida343fc42ba3a817a4f380255596e7fb7fcdfb9b
parent ada2f7e1
Loading
Loading
Loading
Loading
+93 −0
Original line number Diff line number Diff line
@@ -48,16 +48,23 @@ import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.WorkSource;
import android.os.AsyncTask;
import android.provider.Settings;
import android.util.Log;
import android.util.Slog;

import java.io.FileNotFoundException;
import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;

import java.net.InetAddress;
import java.net.Inet4Address;
import java.util.ArrayList;
import java.util.List;

import java.util.concurrent.atomic.AtomicBoolean;

import com.android.internal.R;
@@ -748,6 +755,92 @@ public final class WifiService extends IWifiManager.Stub {
        mWifiStateMachine.clearBlacklist();
    }

    /**
     * enable TDLS for the local NIC to remote NIC
     * The APPs don't know the remote MAC address to identify NIC though,
     * so we need to do additional work to find it from remote IP address
     */

    class TdlsTaskParams {
        public String remoteIpAddress;
        public boolean enable;
    }

    class TdlsTask extends AsyncTask<TdlsTaskParams, Integer, Integer> {
        @Override
        protected Integer doInBackground(TdlsTaskParams... params) {

            // Retrieve parameters for the call
            TdlsTaskParams param = params[0];
            String remoteIpAddress = param.remoteIpAddress.trim();
            boolean enable = param.enable;

            // Get MAC address of Remote IP
            String macAddress = null;

            BufferedReader reader = null;

            try {
                reader = new BufferedReader(new FileReader("/proc/net/arp"));

                // Skip over the line bearing colum titles
                String line = reader.readLine();

                while ((line = reader.readLine()) != null) {
                    String[] tokens = line.split("[ ]+");
                    if (tokens.length < 6) {
                        continue;
                    }

                    // ARP column format is
                    // Address HWType HWAddress Flags Mask IFace
                    String ip = tokens[0];
                    String mac = tokens[3];

                    if (remoteIpAddress.equals(ip)) {
                        macAddress = mac;
                        break;
                    }
                }

                if (macAddress == null) {
                    Slog.w(TAG, "Did not find remoteAddress {" + remoteIpAddress + "} in " +
                            "/proc/net/arp");
                } else {
                    enableTdlsWithMacAddress(macAddress, enable);
                }

            } catch (FileNotFoundException e) {
                Slog.e(TAG, "Could not open /proc/net/arp to lookup mac address");
            } catch (IOException e) {
                Slog.e(TAG, "Could not read /proc/net/arp to lookup mac address");
            } finally {
                try {
                    if (reader != null) {
                        reader.close();
                    }
                }
                catch (IOException e) {
                    // Do nothing
                }
            }

            return 0;
        }
    }

    public void enableTdls(String remoteAddress, boolean enable) {
        TdlsTaskParams params = new TdlsTaskParams();
        params.remoteIpAddress = remoteAddress;
        params.enable = enable;
        new TdlsTask().execute(params);
    }


    public void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable) {
        mWifiStateMachine.enableTdls(remoteMacAddress, enable);
    }

    /**
     * Get a reference to handler. This is used by a client to establish
     * an AsyncChannel communication with WifiService
+4 −0
Original line number Diff line number Diff line
@@ -110,5 +110,9 @@ interface IWifiManager
    String getConfigFile();

    void captivePortalCheckComplete();

    void enableTdls(String remoteIPAddress, boolean enable);

    void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable);
}
+38 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.os.Messenger;
import android.util.Log;
import android.util.SparseArray;

import java.net.InetAddress;
import java.util.concurrent.CountDownLatch;

import com.android.internal.util.AsyncChannel;
@@ -1132,6 +1133,43 @@ public class WifiManager {
        }
    }


    /**
     * Enable TDLS on a specific local route
     *
     * This API is used by WiFi display, but eventually it can be made public,
     * just depends on how popular TDLS gets
     *
     * @param remoteIPAddress IP address of the endpoint to setup TDLS with
     * @param enable true = setup and false = tear down TDLS
     * @hide
     */
    public void enableTdls(InetAddress remoteIPAddress, boolean enable) {
        try {
            mService.enableTdls(remoteIPAddress.getHostAddress(), enable);
        } catch (RemoteException e) {
            // Just ignore the exception
        }
    }

    /**
     * Enable TDLS on a specific local route
     *
     * This API is used by WiFi display, but eventually it can be made public,
     * just depends on how popular TDLS gets
     *
     * @param remoteMacAddress MAC address of the remote endpoint such as 00:00:0c:9f:f2:ab
     * @param enable true = setup and false = tear down TDLS
     * @hide
     */
    public void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable) {
        try {
            mService.enableTdlsWithMacAddress(remoteMacAddress, enable);
        } catch (RemoteException e) {
            // Just ignore the exception
        }
    }

    /* TODO: deprecate synchronous API and open up the following API */

    private static final int BASE = Protocol.BASE_WIFI_MANAGER;
+7 −0
Original line number Diff line number Diff line
@@ -370,6 +370,13 @@ public class WifiNative {
        doBooleanCommand("SCAN_INTERVAL " + scanInterval);
    }

    public void startTdls(String macAddr, boolean enable) {
        if (enable)
            doBooleanCommand("TDLS_SETUP " + macAddr);
        else
            doBooleanCommand("TDLS_TEARDOWN " + macAddr);
    }

    /** Example output:
     * RSSI=-65
     * LINKSPEED=48
+17 −0
Original line number Diff line number Diff line
@@ -337,6 +337,8 @@ public class WifiStateMachine extends StateMachine {
    static final int CMD_SET_FREQUENCY_BAND               = BASE + 90;
    /* Enable background scan for configured networks */
    static final int CMD_ENABLE_BACKGROUND_SCAN           = BASE + 91;
    /* Enable TDLS on a specific MAC address */
    static final int CMD_ENABLE_TDLS                      = BASE + 92;

    /* Commands from/to the SupplicantStateTracker */
    /* Reset the supplicant state tracker */
@@ -1073,6 +1075,14 @@ public class WifiStateMachine extends StateMachine {
        sendMessage(CMD_SET_FREQUENCY_BAND, band, 0);
    }

    /**
     * Enable TDLS for a specific MAC address
     */
    public void enableTdls(String remoteMacAddress, boolean enable) {
        int enabler = enable ? 1 : 0;
        sendMessage(CMD_ENABLE_TDLS, enabler, 0, remoteMacAddress);
    }

    /**
     * Returns the operational frequency band
     */
@@ -2595,6 +2605,13 @@ public class WifiStateMachine extends StateMachine {
                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
                    }
                    break;
                case CMD_ENABLE_TDLS:
                    if (message.obj != null) {
                        String remoteAddress = (String) message.obj;
                        boolean enable = (message.arg1 == 1);
                        mWifiNative.startTdls(remoteAddress, enable);
                    }
                    break;
                default:
                    return NOT_HANDLED;
            }