diff --git a/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/AbstractWifiFragment.java b/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/AbstractWifiFragment.java index 80da568..ba3c299 100644 --- a/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/AbstractWifiFragment.java +++ b/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/AbstractWifiFragment.java @@ -14,6 +14,7 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; +import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -35,6 +36,7 @@ import java.util.Timer; import java.util.TimerTask; +import javax.crypto.Mac; public abstract class AbstractWifiFragment extends Fragment { @@ -62,6 +64,9 @@ public abstract class AbstractWifiFragment extends Fragment { // hold target wifi ssid private String mTargetSsid; + // hold target wifi bssid + private String mTargetBssid; + public AbstractWifiFragment() { mTimer = new Timer(); } @@ -154,6 +159,7 @@ public void onResume() { /** * Starts the wifi connection to the specified ssid * @param targetSsid Target Wifi SSID to connect to + * @param targetBssid (Optional) Target BSSID * @param targetPassphrase (Optional) Wifi passphrase to use * @param reason A reason to show to the user that explains why Wifi is being requested. * @param timeout Number of milliseconds to wait before issuing a timeout to the wifi operation @@ -162,6 +168,7 @@ public void onResume() { * is automatically requested by this method. */ public void startWifiConnection(String targetSsid, + @Nullable String targetBssid, @Nullable String targetPassphrase, @Nullable String reason, int timeout) throws PermissionNotGrantedException { @@ -196,12 +203,13 @@ public void startWifiConnection(String targetSsid, // Store ssid for callback later usage mTargetSsid = targetSsid; + mTargetBssid = targetBssid; // Since Android Q, Android requires the developer to work with NetworkRequest API. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { startWifiConnectionLegacy(targetSsid, targetPassphrase, timeout); } else { - startWifiConnectionAndroidQ(targetSsid, targetPassphrase, timeout); + startWifiConnectionAndroidQ(targetSsid, targetBssid, targetPassphrase, timeout); } } @@ -267,9 +275,14 @@ private void startWifiConnectionLegacy(String ssid, @Nullable String passphrase, } @RequiresApi(api = Build.VERSION_CODES.Q) - private void startWifiConnectionAndroidQ(String ssid, @Nullable String passphrase, int timeout) { + private void startWifiConnectionAndroidQ(String ssid, @Nullable String bssid, @Nullable String passphrase, int timeout) { WifiNetworkSpecifier.Builder specifierBuilder = new WifiNetworkSpecifier.Builder() .setSsid(ssid); + + if (bssid != null) { + specifierBuilder.setBssid( MacAddress.fromString(bssid)); + } + if (passphrase != null) specifierBuilder.setWpa2Passphrase(passphrase); @@ -333,7 +346,7 @@ private void unRegisterWifiBroadcastReceiver() { /** * Callback called when the user has granted necessary wifi permissions */ - protected abstract void onWifiPermissionsGranted(String ssid); + protected abstract void onWifiPermissionsGranted(String ssid, @Nullable String bssid); private void notifyWifiConnected() { mWifiConnectionAttemptInProgress = false; @@ -365,12 +378,6 @@ public void onUnavailable() { @Override public void onLost(@NonNull Network network) { super.onLost(network); - - /* - mConnectivityManager.bindProcessToNetwork(null); - mConnectivityManager.unregisterNetworkCallback(this); - // Here you can have a fallback option to show a 'Please connect manually' page with an Intent to the Wifi settings - */ } @Override @@ -454,7 +461,7 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis if (!permsOk) onMissingWifiPermissions(mTargetSsid); else - onWifiPermissionsGranted(mTargetSsid); + onWifiPermissionsGranted(mTargetSsid, mTargetBssid); } } } diff --git a/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/ConfigureWifiFragment.java b/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/ConfigureWifiFragment.java index 8d0b254..53ee186 100644 --- a/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/ConfigureWifiFragment.java +++ b/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/ConfigureWifiFragment.java @@ -1,6 +1,7 @@ package com.albertogeniola.merossconf.ui.fragments.pair; import android.content.Context; +import android.net.MacAddress; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; import android.os.Bundle; @@ -215,8 +216,8 @@ protected void onMissingWifiPermissions(String ssid) { @SneakyThrows(PermissionNotGrantedException.class) @Override - protected void onWifiPermissionsGranted(String ssid) { - startWifiConnection(ssid, mSelectedWifi.getClearWifiPassword(), null, 60000); + protected void onWifiPermissionsGranted(String ssid, @Nullable String bssid) { + startWifiConnection(ssid, bssid, mSelectedWifi.getClearWifiPassword(), null, 60000); } @UiThread @@ -331,7 +332,7 @@ private void startWifiConnectionValidation(WifiConfiguration selectedWifi) { // Start wifi connection try { - startWifiConnection(mSelectedWifi.getScannedWifi().getSsid(), mSelectedWifi.getClearWifiPassword(), null, 20000); + startWifiConnection(mSelectedWifi.getScannedWifi().getSsid(), mSelectedWifi.getScannedWifi().getBssid(), mSelectedWifi.getClearWifiPassword(), null, 20000); // The flow starts back from on onWifiConnected / onWifiUnavailable(). } catch (PermissionNotGrantedException e) { // The flow starts back from onWifiPermissionsGranted() diff --git a/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/ExecutePairingFragment.java b/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/ExecutePairingFragment.java index 4e691e4..a33ebc3 100644 --- a/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/ExecutePairingFragment.java +++ b/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/ExecutePairingFragment.java @@ -1,5 +1,6 @@ package com.albertogeniola.merossconf.ui.fragments.pair; +import android.net.MacAddress; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -114,7 +115,7 @@ private void connectToDeviceWifiAp() { String bssid = pairActivityViewModel.getMerossPairingAp().getValue().getBssid(); try { - startWifiConnection(ssid, null, null, 15000); + startWifiConnection(ssid, bssid,null, null, 15000); // Flow starts again from onWifiConnected() / onWifiUnavailable() } catch (PermissionNotGrantedException e) { Log.e(TAG, "Missing wifi permissions"); @@ -127,12 +128,13 @@ private void connectToLocalWifi() { state = State.CONNETING_LOCAL_WIFI; String ssid = pairActivityViewModel.getMerossConfiguredWifi().getValue().getScannedWifi().getSsid(); + String bssid = pairActivityViewModel.getMerossConfiguredWifi().getValue().getScannedWifi().getBssid(); String passphrase = pairActivityViewModel.getMerossConfiguredWifi().getValue().getClearWifiPassword(); // Check if we are already connected to such wifi // TODO: Check comparison happens with double quotes try { - startWifiConnection(ssid, passphrase, null, 60000); + startWifiConnection(ssid, bssid, passphrase, null, 60000); // Flow starts again from onWifiConnected() / onWifiUnavailable() } catch (PermissionNotGrantedException e) { Log.e(TAG, "Missing wifi permissions"); @@ -384,7 +386,7 @@ protected void onMissingWifiPermissions(String ssid) { } @Override - protected void onWifiPermissionsGranted(String ssid) { + protected void onWifiPermissionsGranted(String ssid, @Nullable String bssid) { String pairingSsid = pairActivityViewModel.getMerossPairingAp().getValue().getSsid(); String localSsid = pairActivityViewModel.getMerossConfiguredWifi().getValue().getScannedWifi().getSsid(); diff --git a/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/FetchDeviceInfoFragment.java b/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/FetchDeviceInfoFragment.java index 292a482..66f954f 100644 --- a/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/FetchDeviceInfoFragment.java +++ b/app/src/main/java/com/albertogeniola/merossconf/ui/fragments/pair/FetchDeviceInfoFragment.java @@ -123,8 +123,9 @@ private void stateMachine(Signal signal) { private void connectAp() { String ssid = pairActivityViewModel.getMerossPairingAp().getValue().getSsid(); + String bssid = pairActivityViewModel.getMerossPairingAp().getValue().getBssid(); try { - startWifiConnection(ssid, null, null, CONNECT_AP_TIMEOUT); + startWifiConnection(ssid, bssid,null, null, CONNECT_AP_TIMEOUT); // The flow starts back from on onWifiConnected / onWifiUnavailable(). } catch (PermissionNotGrantedException e) { Log.w(TAG, "Missing user permissions."); @@ -260,8 +261,8 @@ protected void onMissingWifiPermissions(String ssid) { @SneakyThrows(PermissionNotGrantedException.class) @Override - protected void onWifiPermissionsGranted(String ssid) { - startWifiConnection(ssid, null, null, 10000); + protected void onWifiPermissionsGranted(String ssid, @Nullable String bssid) { + startWifiConnection(ssid, bssid,null, null, 10000); } @Override