Xamarin WiFi SmartConfig integrating ESP8266 and ESP32

SmartConfig is a really interesting feature available in low-cost ESP board.

If you ever played around with Arduino and its various brother and modules for wifi communication, you should have faced one common issue. Setting up the WiFi connection.

In a real world application you can’t just hardcode the wifi password in every single appliance of your customer.
They expect you to provide them with a clever tool or app that allows them to configure their new IOT thing just by pressing a button.

This actually possible thanks to this SmartConfig feature on ESP boards. Basically the WiFi start sniffing the air looking for a special UDP package, which has been tailored to contain alla the necessary information to connect to a WiFi in range.

SmartConfig comes with a two libraries for iOS and Android that can be integrated in your apps to make the SmartConfig magic. You can find on both store a thousand apps to make the SmartConfig magic.

Bad guys like us love make thing cross platform with Xamarin

I was so disappointed when I figured out that there was no Xamarin Library for Smart Config. Fortunately Xamarin has a powerful system to wrap up external libraries and make them available to your Droid and iOS projects, and I spent a few hours making them up for you.

You find Smart Config for Xamarin.iOS, Xamarin.Droid and Xamarin.Forms here on Nuget

or just cut and paste and put it on PM

Install-Package EspTouchSmartConfigXamarin -Version 1.0.3

and for the ones like me who loves terminal

dotnet add package EspTouchSmartConfigXamarin --version 1.0.3

How to use SmartConfig in your Xamarin.Forms project

First of all you should install the package from nuget in all your project (Forms, iOS, Droid). There is no EspTouch Library for Windows Phone from the ESP team, so WP developers you should have a look around or implement your own SmartConfig you can start from Texas Instruments Spec.

You need then to make available to forms the real implementation of the SmartConfig Library using Dependency Service.
This is quite straight forward as we already provided a interface that wraps the original methods of the Library.

 
     public interface ISmartConfigTask
     {

         ISmartConfigResult executeForResult ();
 
         List executeForResults (int expectTaskResultCount);
 
         void SetSmartConfigTask (string ssid, string bssid, string passphrase);
 
         void SetSmartConfigTask (string ssid, string bssid, string passphrase, bool isHidden);
 
         void SetSmartConfigTask (string ssid, string bssid, string passphrase, bool isHidden, int timeoutMillis);
     }

The logic behind launch a process that start sending UDP packages on the active WiFi and looks for a package back from the device, when the package is back an ISmartConfigResult is created with all the information from the device. The most important information is the device’s IP in the network, so that you can call some endpoint in your device and expect a JSON response or so.

Last you need to instantiate a new Task in Forms, wait for answer(s) and make your stuff. Let’s the whole process.

Xamarin.iOS

Install the package from Nuget

Install-Package EspTouchSmartConfigXamarin -Version 1.0.3

Create a new class SmartConfig_iOS that is the real implementation of ISmartConfig. If you have not added the Nuget package to the PCL project than you’ll get an error, which will be fixed as soon as you’ll install it.

 using System;
 using EspTouchMultiPlatformLIbrary;
 using Xamarin.Forms;
 
 [assembly: Dependency(typeof(yournamespace.iOS.SmartConfig_iOS))]
 namespace yournamespace.iOS
 {
     public class SmartConfig_iOS : ISmartConfigHelper
     {
         public SmartConfig_iOS()
         {
         }
 
         public ISmartConfigTask CreatePlatformTask()
         {
             return new SmartConfigTask_iOS();
         }
     }
 }

Xamarin.Droid

Install the package from Nuget

Install-Package EspTouchSmartConfigXamarin -Version 1.0.3

Create a new class SmartConfig_Droid that is the real implementation of ISmartConfig. If you have not added the Nuget package to the PCL project than you’ll get an error, which will be fixed as soon as you’ll install it.

 using System;
 using EspTouchMultiPlatformLIbrary;
 using Xamarin.Forms;
 
 [assembly: Dependency(typeof(yournamespace.Droid.SmartConfig_Droid))]
 namespace yournamespace.Droid
 {
     public class SmartConfig_Droid : ISmartConfigHelper
     {
         public SmartConfig_Droid()
         {
         }
 
         public ISmartConfigTask CreatePlatformTask()
         {
             return new SmartConfigTask_Droid();
         }
     }
 }

Xamarin.Forms

Install the package from Nuget

Install-Package EspTouchSmartConfigXamarin -Version 1.0.3

The most work is here in Xamarin.Forms, as we should expect from a cross platform solution. This is the unique advantage of Xamarin. 99% of your code is portable.

First create an helper class for the DepencyService, this will fix any previous error in iOS and Droid projects.

 using System;
 using EspTouchMultiPlatformLIbrary;
 
 namespace yournamespace
 {
     public interface ISmartConfigHelper
     {
         ISmartConfigTask CreatePlatformTask();
     }
 }

In your ViewModel or in your Code Behind or wherever your app need to configure the device you should call the Smart Config Task in this way:

ISmartConfigTask smartconfig = DependencyService.Get<ISmartConfigHelper>().CreatePlatformTask();
 
smartconfig.SetSmartConfigTask(Ssid, Bssid, Passphrase, false60000);

await Task.Run(() =>
{
    var result = smartconfig.executeForResult();
    if (result.isSuc())
    {
        SetupRequired = false;
        DeviceIp = result.getInetAddress();
    }
});

It is a really simple example, you first have to get the SmartConfigTask object from the Dependency Service and you set a few parameters:

Ssid = your network ssid (the one you want to configure)
Bssid = your network bssid (the one you want to configure)
Passphrase = your network passphrase (the one you want to configure)
isHidden = true or false if the Ssid is hidden
Timeout = how long you’ll wait for answer. 60 sec might seems too much, but sometimes are necessary.

Secondly, you need to wrap the call to “executeForResult()” in a Task, if you don’t do that this task will run on main thread and the whole app will starve waiting for its completion.

Conclusions

SmartConfig is a powerful feature of ESP boards, but for the ones who are already using the ESP32 that integrates BLE, than it would be nicer to use Bluetooth to send configuration info to your board. I will soon publish an article on this!! Stay connected and follow me on twitter to keep up to date!

The Library are open source, you can contribute to the porting of the original library on GitHub

https://github.com/lucafabbri/EspTouchBinding-Xamarin-iOS-Droid

Comment below, I usually make a lot of typos, I apologize!

Annunci

8 pensieri riguardo “Xamarin WiFi SmartConfig integrating ESP8266 and ESP32

  1. Amazing work! Thank you for sharing it!!!

    I’m having trouble with the Bssid parameter.

    I’ve try so far:
    Bssid = “20-AA-4B-33-60-7A”;
    = “20AA4B33607A”;
    = “0x20aa4b33607a”;
    = “35915778187386”;

    I’m alway getting an error that stipulates that the Bbssid is not a valid int.

    Thanks!

    Mi piace

  2. Ciao Felice! Glad you enjoyed this guide 🙂
    Bssid is an int that comes as an info from the wifi itself. the underlying SO should expose some function to get this info from the WiFi Manager.
    If you are integrating this in Xamarin.Forms then you’d better use DependecyService to expose a platform specific implementation of WiFi Manager getSsid and getBssid. Hereafter an example.

    public interface IWifiInfo
    {
    String getSsid();
    String getBssid();
    }
    —————————————
    using System;
    using Android.Content;
    using Android.Net.Wifi;
    using Xamarin.Forms;

    [assembly: Dependency(typeof(example.Droid.WifiInfo_Droid))]
    namespace example.Droid
    {
    public class WifiInfo_Droid : IWifiInfo
    {
    WifiManager wifiManager;
    public WifiInfo_Droid()
    {
    wifiManager = (WifiManager)(Forms.Context.GetSystemService(Context.WifiService));
    }

    public string getBssid()
    {
    if (wifiManager != null)
    {
    return wifiManager.ConnectionInfo.BSSID;
    }
    else
    {
    return “”;
    }
    }

    public string getSsid()
    {
    if (wifiManager != null)
    {
    return wifiManager.ConnectionInfo.SSID;
    }
    else
    {
    return “”;
    }
    }
    }
    }
    —————————————
    using System;
    using Foundation;
    using SystemConfiguration;
    using Xamarin.Forms;

    [assembly: Dependency(typeof(example.iOS.WifiInfo_iOS))]
    namespace example.iOS
    {
    public class WifiInfo_iOS : IWifiInfo
    {
    public WifiInfo_iOS()
    {
    }

    public string getBssid()
    {
    NSDictionary dict;
    var status = CaptiveNetwork.TryCopyCurrentNetworkInfo(“en0”, out dict);
    if (status == StatusCode.NoKey || dict == null || dict.Count == 0)
    return String.Empty;
    var ssid = dict[CaptiveNetwork.NetworkInfoKeyBSSID];
    return ssid.ToString();
    }

    public string getSsid()
    {
    NSDictionary dict;
    var status = CaptiveNetwork.TryCopyCurrentNetworkInfo(“en0”, out dict);
    if(status == StatusCode.NoKey || dict == null || dict.Count == 0){
    return String.Empty;
    }
    var ssid = dict[CaptiveNetwork.NetworkInfoKeySSID];
    return ssid.ToString();
    }
    }
    }

    Mi piace

    1. Dear Luca Fabbri,

      Thank you for your kind and helpful response.

      I implemented your suggestion, now I’m getting the same mac-address but with this convention: “20:aa:4b:XX:XX:XX”.

      And it works beautifully!

      I’m getting the IP address in the ESP32 perfectly!

      I’m still figuring out another problem, although the Smart Config process succeeded from the viewpoint of the ESP32, the Xamarin Forms App instantly crash during this process, with and Unhandled Exception that I can’t even catch inside a Try Catch block

      I’m running the code in Android, I don’t have an iPhone to test it.
      I’m using v1.0.4 of your library and a Samsung Galaxy S4.

      This is the code:

      private async void BtnConnect_Clicked(object sender, EventArgs e)
      {

      ISmartConfigTask smartconfig = DependencyService.Get().CreatePlatformTask();

      string bssid = DependencyService.Get().GetBSSID();

      smartconfig.SetSmartConfigTask(this.txtSSID.Text, bssid, this.txtPassword.Text, this.chkNetworkIsHidden.IsToggled, 60000);

      await Task.Run(() =>
      {
      try
      {
      var result = smartconfig.executeForResult();
      if (result.isSuc())
      {
      var SetupRequired = false;
      var DeviceIp = result.getInetAddress();
      }
      }
      catch (Exception ex)
      {
      var x = “Dummy just to attach a BreakPoint”;
      //Device.BeginInvokeOnMainThread(() =>{DisplayAlert(“Error”, ex.Message, “OK”);});
      }
      });
      }

      }

      Thanks again!!

      Mi piace

  3. Oi Luca Fabbri!

    Congratulations on your work.

    Can you help me with this error please? I am new to xamarin:
    I can install on android and ios, but in forms gives this error:

    The ‘EspTouchSmartConfigXamarin 1.0.4’ package could not be installed.
    You are trying to install this package in a project that is intended for ‘.NETPortable, Version = v4.5, Profile = Profile259’,
    but the package does not contain any assembly or content reference that is compatible with this framework.

    Thank you very much!!

    Mi piace

    1. This usually happens when you added the .Forms project afterwards. You’d rather search stack overflow for similar issues on .Net version and package installation. This is not related to the library itself I guess.

      Mi piace

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

w

Connessione a %s...