Search code examples
androidandroid-wifi

Is there a way to programmatically connect to a Passpoint/Hotspot2.0 network via EAP-TTLS?


I'm trying to create either a WifiConfiguration object or PasspointConfiguration object in my Android application that will allow me to connect a device to a Passpoint network upon being enabled.

I've tried to connect by building a WifiConfiguration object and adding it to the WifiManager, then enabling it.

I have also tried to build a PasspointConfiguration object, but when I try to run WifiManager.addOrUpdatePasspointConfiguration() with the PasspointConfiguration object, the app crashes with an IllegalArgumentException. I'm assuming that this is an invalid configuration issue.

// WifiConfiguration/WifiEnterpriseConfiguration approach
WifiConfiguration wc = new WifiConfiguration();
wc.status = WifiConfiguration.Status.ENABLED;
wc.isHomeProviderNetwork = true;
wc.FQDN = this.domain;
wifiEnterpriseConfig.setIdentity(user);
wifiEnterpriseConfig.setPassword(key);
wifiEnterpriseConfig.setAnonymousIdentity(this.outerID);
wifiEnterpriseConfig.setRealm(this.realm);
wifiEnterpriseConfig.setDomainSuffixMatch(this.domain);
wifiEnterpriseConfig.setEapMethod(this.eapMethod);
wifiEnterpriseConfig.setPhase2Method(this.phase2Auth);
wifiEnterpriseConfig.setCaCertificate(this.cert);

wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);

wc.enterpriseConfig = wifiEnterpriseConfig;

wifiManager.disconnect();
this.networkID = wifiManager.addNetwork(wc);
wifiManager.enableNetwork(this.networkID, true);
// PasspointConfiguration approach
Credential.UserCredential userCredential = new Credential.UserCredential();
userCredential.setEapType(21);
userCredential.setPassword(key);
userCredential.setUsername(user);
userCredential.setNonEapInnerMethod("MS-CHAP-V2");

Credential credential = new Credential();
credential.setRealm(this.realm);
credential.setUserCredential(userCredential);
credential.setCertCredential(null);
credential.setCaCertificate(null);
credential.setClientPrivateKey(null);
credential.setClientCertificateChain(null);

HomeSp homeSp = new HomeSp();
homeSp.setFqdn(this.domain);
homeSp.setFriendlyName(this.friendlyName);

PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
passpointConfiguration.setCredential(credential);
passpointConfiguration.setHomeSp(homeSp);

wifiManager.addOrUpdatePasspointConfiguration(passpointConfiguration);

I expect the application to connect the device to the Passpoint/Hotspot2.0 network upon one of the configurations being added to the WifiManager.

The first approach does not produce an error, but does not connect the application to the network.

The following is the stack trace from the PasspointConfiguration IllegalArgumentException:

Process: com.***.***.***, PID: 4101
    java.lang.IllegalArgumentException
        at android.net.wifi.WifiManager.addOrUpdatePasspointConfiguration(WifiManager.java:1483)
        at com.***.***.***.models.<PrivateClass>.<PrivateMethod1>(<PrivateClass>.java:197)
        at com.***.***.***.models.<PrivateClass>.<PrivateMethod2>(<PrivateClass>.java:219)
        at com.***.***.***.models.<PrivateClass>.<PrivateMethod3>(<PrivateClass>.java:116)
        at com.***.***.***.UserView.<PrivateMethod4>(UserView.java:178)
        at com.***.***.***.UserView.access$100(UserView.java:34)
        at com.***.***.***.UserView$2.onClick(UserView.java:200)
        at android.view.View.performClick(View.java:7327)
        at android.widget.TextView.performClick(TextView.java:14160)
        at android.view.View.performClickInternal(View.java:7299)
        at android.view.View.access$3200(View.java:846)
        at android.view.View$PerformClick.run(View.java:27774)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:6981)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)

Solution

  • The key used in userCredential.setPassword(key) must be base 64 encoded before setting it to the userCredential.