Wednesday, June 7, 2017

Enable TLS 1.2 & 1.1 Xamarin.Android JellyBean & KitKat



  TLS or Transport Layer Security is a cryptographic protocol that provides communication security over a computer network. If you develop for both iOS and Android you probably know that on iOS by default enforces TLS v1.2 for any application (that, for the moment, you can disable).
  When developing for iOS and Android using Xamarin you will probably end up using the HttpClient class. The default implementation of HttpClient on Mono only has built-in support for TLS v1.0. This is why, in order to use the newer versions of TLS, you would had to implement a class derived from HttpClientHandler that under the hood uses the native classes included in the platform that already support  newer TLS versions . The first choice, for a while, was the ModerHttpClient that NSUrlSession class on iOS and OkHttp on Android.
   Recently Xamarin added its own native HttpClientHandler in both iOS and Android. You can are free to switch from the fully managed one or the native one (which imho is recommended). To set the default implementation you will have to go in the project's settings dialog.

    There a small detail for the Android native implementation.  The Xamarin TLS document tells you that v1.2 is only supported for Android >= 5.0 . On the other side if you go to Wikipidia TLS Document you will see that TLS v.1.1 & v1.2 are supported by Android >= 4.1 but they are not enabled by default until Android 5.0.
  If you try to use TLS v1.1& 1.2 on an Android device version >4.0 & <5.0, as these protocols are not enabled by default you will get an "Connection closed by peer" exception.
     There is actually a simple solution for this problem: in order to enable TLS v1.1 & 1.2 in Android JellyBean & KitKat you will have to implement a class derived from SSLSocketFactory and enable the protocols and than change the factory that AndroidClientHandler uses by default. This can easily be achieved by using a implementing a class derived from  AndroidClientHandler where you will override the method SetupRequest and change the SSLSocketFactory with our own implementation that enables TLS v1.1 & 1.2 on the SSLSocket it creates:


  public class AndroidCustomClientHandler:AndroidClientHandler
    {
        CustomTlsSSLSocketFactory _customTlsSSLSocketFactory=new CustomTlsSSLSocketFactory();
        protected override System.Threading.Tasks.Task SetupRequest(System.Net.Http.HttpRequestMessage request, Java.Net.HttpURLConnection conn)
        {
            if (conn is HttpsURLConnection)
            {
                if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop)
                    //Enable support for TLS v1.2
                    ((HttpsURLConnection)conn).SSLSocketFactory = _customTlsSSLSocketFactory;
            }
            return base.SetupRequest(request, conn);
        } 
    }


where CustomTlsSSLSocketFactory is this:


public class CustomTlsSSLSocketFactory : SSLSocketFactory
 {
  readonly SSLSocketFactory factory = (SSLSocketFactory)Default;

  public override string[] GetDefaultCipherSuites()
  {
   return factory.GetDefaultCipherSuites();
  }

  public override string[] GetSupportedCipherSuites()
  {
   return factory.GetSupportedCipherSuites();
  }
  public override Java.Net.Socket CreateSocket(Java.Net.InetAddress address, int port, Java.Net.InetAddress localAddress, int localPort)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(address, port, localAddress, localPort);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  public override Java.Net.Socket CreateSocket(Java.Net.InetAddress host, int port)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(host, port);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  public override Java.Net.Socket CreateSocket(string host, int port, Java.Net.InetAddress localHost, int localPort)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(host, port, localHost, localPort);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  public override Java.Net.Socket CreateSocket(string host, int port)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(host, port);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  public override Java.Net.Socket CreateSocket(Java.Net.Socket s, string host, int port, bool autoClose)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(s, host, port, autoClose);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  protected override void Dispose(bool disposing)
  {
   factory.Dispose();
   base.Dispose(disposing);
  }

  public override Java.Net.Socket CreateSocket()
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket();
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }
 }


You can see that I've chosen to enable all the supported protocols, but a better approach would be to enable just the ones that you actually use.

Hope you will find it useful!

I almost forgot the most important part: When you initialize your HttpClient you will have to pass an instance of your AndroidCustomClientHandler class:


 HttpClient _client = new HttpClient(new AndroidCustomClientHandler()) { BaseAddress = _baseAddr };

Saturday, February 18, 2017

UWP Shake Gestures

 The Accelerometer class available in UWP starting with version 10240 has an event called Shaken that should be raised when a shake event occurs without having to subscribe to the Accelerometer raw data. This event was never implemented so if you try to use it, it won't work.
  On my quest for starting from something already validated I've came along an old post from the Windows Blog for a Windows Phone Shake Gesture Library.
  After finding the source code of the library I did a simple port to the UWP which you can find on the ShakeGestures.UWP GitHub repository.
  Hope that some of you will find it useful. Btw there is also the Sample application in the same repository.

  P.S. Still planning some posts on the new Bluetooth functionality available in UWP SDK for the Creators Update and some from the Anniversary Update and hopefully I will find some spare time soon.

  

Sunday, September 27, 2015

Using iBeacons with Windows 10 - Part I

It’s been a while since my last post on the blog, but it was such a busy period and sadly my blog is not one of my main priorities. Would really love to find more time for writing.
This post is focused on “consuming” iBeacon devices around us and also configuring your device as an iBeacon using the newly added functionality in the Universal Windows Platform target Windows 10 Build 10240. 
A little bit of introduction to the beacon/Bluetooth technology. The iBeacon functionality is built on-top of the Bluetooth Low Energy (BLE) and enables to create a region around an object. This allows client devices (Android, Windows, iOS) to determine when it has entered or left a region along with an estimation of proximity to the beacon. The BLE standard architecture (and not only) is a client-server one. The device that exposes the functionality is the server (in our case the beacon) and our device (phone, tablet) is the client. In order for a client to know that a server is in range the server advertise itself (sending bytes packages at certain intervals times on different radio channels). The battery life of an BLE device depends mainly of the advertising interval (this is because usually the device is idle and advertising). With one advertising packages each second the lifetime of a beacon device running on a CR2032 battery is about 1 year. The client on the other side is scanning the communications channels for Bluetooth advertising.


Here is how an advertising package looks like:


The  “standard sequence” includes: 

  • Preamble and Access Address is always the same 
  • Packet Data Unit
  • CRC to understand if the received package is correct or not.
The PDU can have a length between 8 and 39 bytes where the first 4 bits is the PDU type. For this post we are interested in two types ADV_IND – Connectable Undirected Advertising meaning a device that is advertising and it can be connected to and ADV_NONCONN_IND Non connectable undirected advertising is a device advertising but not connectable. If you want to better understand the advertising package read this post http://j2abro.blogspot.it/2014/06/understanding-bluetooth-advertising.html and the complete list of AD Type can be found here: https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
So we could consider a Beacon any Bluetooth Low Energy that is advertising. The iBeacon (and EddyStone but that we will address in another post) is just a standard advertising package. 

The structure of the iBeacon packages is:


The iBeacon prefix bytes are always the same:

iBeacon Prefix
02
Number of bytes that follow (AD Length)
01
AD Type
06
Flags type
1A
26 bytes that follow in the second AD structure (AD Length)
FF
Manufacturer specific data AD Type
4C 00
Company identifier 0x004C = Apple
02
Secondary ID that denotes a proximity beacon, which is used by all iBeacons
15
defines the remaining length to be 21 bytes

              The developers can configure for each iBeacon (using the tools that manufacturers provide) the UUID, Major, Minor and TX Power. 
        Here is how the advertising looks like from an Estimote iBeacon. The package was captured using Packet Sniffer from Texas Instruments:


              As you can see the device can be connected to because the advertising type is ADV_IND but this is not always true. If you have a generation 1 Texas Instruments SimpleLink SensorTag with the iBeacon firmware flushed you can switch between “normal” mode and iBeacon mode and the device in iBeacon mode cannot be connected (it is only an iBeacon without any service). Here is the package captured by the sniffer:



Btw if you want to update the Gen 1 SensorTag to the iBeacon firmware you can follow these instructions. I haven’t compiled the source code but downloaded the firmware from this link. You will need an Android or an iOS device even if right now the TI application is broken for both Android 5 and iOS 9 (I had to roll back to iOS 8 in order to update the SensorTag firmware). If you look at the two packges you will see that the SensorTag is missing and ADV sequence 02 01 06 but because we are going to filter using the ManufacturerData we will still intercept this type of iBeacona correctly.
Also remember that the only Beacon standard supported by all the mobile platforms iOS, Android, Windows is iBeacon.  Windows 10 and Android can actually support natively any type of Beacon.

              After the standard Prefix we have the actual data of the iBeacon:

Field
Size
Description
UUID
16 bytes
Application developers should define a UUID specific to their app and deployment use case.
Major
2 bytes
Further specifies a specific iBeacon and use case. For example, this could define a sub-region within a larger region defined by the UUID.
Minor
2 bytes
Allows further subdivision of region or use case, specified by the application developer.
TX Power
1 bytes
The calibrated(known) measured signal strength in Rssi at 1 meter

You might find on some websites that the Tx Power length is 2 bytes but it is not true. The Tx Power is 1 byte signed.
For the tests and development, I have used both an Estimote beacon and the SensorTag with the iBeacon firmware.

So now let’s get back to Windows 10 and the new SDK. We now have support for:
  • BluetoothLEAdvertisementWatcher - capturing advertising packages in the foreground
  • BluetoothLEAdvertisementPublisher – set a new advertising package for the
  • BluetoothLEAdvertisementWatcherTrigger – the same as the watcher only that it sets a trigger and the code associated with the trigger will run in the background even if the application is not in the foreground or running
  • BluetoothLEAdvertisementPublisherTrigger – the counter part of the advertising publisher for advertising in the background

IMPORTANT: even if a device advertises ADV_IND meaning that a client can connect to it the UWP Bluetooth functionality for Windows 10 build 10240 is still LIMITED because it can only connect to the device if it was previously paired with Windows. For the moment there is no way to pair to new devices from code so the application would open the Bluetooth window, the user have to manually pair with the device and then, when coming back to the application, we can connect to the device and enumerate services and characteristics.
If we want to monitor for iBeacons only in the foreground (while our application is running) we will use the BluetoothLEAdvertisementWatcher class. 
IMPORTANT: when you create a new project in order to be able to interact with the iBeacons from your UWP project you have to open the Package.appxmanifest file and enable Bluetooth  Capability:


Using BluetoothLEAdvertismentWatcher we can monitor the advertisement packages from any BLE device around us. Of course this is a little bit excessive if we only want/need to monitor a certain class of iBeacon. This can be done using the AdvertisementFilter property of the watcher. To make things easier I have developed a small helper class (that hopefully will grow in time) that will actually set the BluetoothLEAdvertisment with the desired iBeacon sequence.

The extension method uses an iBeaconData class as input:


public class iBeaconData
    {
        public Guid UUID { get; set; }
        public ushort Major { get; set; }
        public ushort Minor { get; set; }
        public short TxPower { get; set; }
        public double Distance { get; set; }
        public short Rssi { get; set; }
        
        public iBeaconData()
        {
            UUID = Guid.Empty;
            Major = 0;
            Minor = 0;
            TxPower = 0;
            Distance = 0;
            Rssi = 0;
        }
    }

To set the BluetootLEAdvertisement you just need to set the iBeacon data and pass it to the extension iBeaconSetAdvertisement. If we pass the class without setting any property we will monitor for all iBeacon advertisement. If we want to monitor the iBeacons with a certain UUID we just have to set the UUID property before calling the extension method. On the other hand if we set the Major property we will also have to set the UUID to which the Major corresponds. If you look at the source code you will see that the filters work in sequence: If we set the Minor we need to set the Major and UUID, if we set the Major we need to also set the UUID. This is because we are looking for certain patterns of bytes in the advertisement package. Here are some samples of the API callesìd:

// Create and initialize a new watcher instance.
watcher = new BluetoothLEAdvertisementWatcher();

// Monitor all iBeacons advertisment
watcher.AdvertisementFilter.Advertisement.iBeaconSetAdvertisement(new iBeaconData());

// Monitor all iBeacons with UUID
watcher.AdvertisementFilter.Advertisement.iBeaconSetAdvertisement(
    new iBeaconData()
    {
        UUID = Guid.Parse("{307f40b9-f8f5-6e46-aff9-25556b57fe6d}")
    });

// Monitor all iBeacons with UUID and Major 
watcher.AdvertisementFilter.Advertisement.iBeaconSetAdvertisement(
    new iBeaconData()
    {
        UUID = Guid.Parse("{307f40b9-f8f5-6e46-aff9-25556b57fe6d}"),
        Major=18012
    });

// Monitor all iBeacons with UUID and Major 
watcher.AdvertisementFilter.Advertisement.iBeaconSetAdvertisement(
    new iBeaconData()
    {
        UUID = Guid.Parse("{307f40b9-f8f5-6e46-aff9-25556b57fe6d}"),
        Major = 18012,
        Minor=1040
    });


The Advertisement filter is not the only filter that you can set for the watcher. You can have a look at all the other parameters of the class on MSDN.
The other helper method, iBeaconParseAdvertisement, helps parsing the received advertisement package and retrieve the iBeacon data: UUID, Major, Minor, TxPower and Distance. The Distance is an approximate one and it is calculated using the TxPower (the Rssi level measured at 1m) and the actual Rssi level. To better understand why is hard to have a really precise value read this blog post about Fundamentals of Beacon Ranging  (on iOS devices the distance is more precise because Apple is the only manufacturer of its devices so he can tune the bluetooth chipset settings to have similar results on all the devices meaning the Rssi level measured on the iPhone at 1m would be almost the same for the iPad or iPod).
In the sample I have subscribed the Received event handler of the watcher an simply called the method iBeaconParseAdvertisement to get the iBeacon data.

// Get iBeacon specific data
var beaconData = eventArgs.Advertisement.iBeaconParseAdvertisement(eventArgs.RawSignalStrengthInDBm);

Now let's see how we can scan for iBeacons from the background (while our application is not running). The SDK adds a new background trigger specific for BLE advertisment that is why it is called BluetoothLEAdvertisementWatcherTrigger. If you don't know how the background tasks work read read this: Creating and register a background task .
The main difference between scanning in the foreground and in the background from the BLE point of view is the minimum sampling period: when scanning in the foreground the value can be 0, while in background the minimum sampling interval is 1 second. We cannot have more than one event/second in the background. If more than one iBeacon has advertised in that period we will find all the advertisements packages using the Advertisements property. Remember also that the background task runs in a different process but in the same container (so the storage is shared).
Also in this case when setting the trigger I am calling the extension method that sets the filter for the advertisement data:

// Create and initialize a new trigger to configure it.
trigger = new BluetoothLEAdvertisementWatcherTrigger();
// Add the manufacturer data to the advertisement filter on the trigger:
trigger.AdvertisementFilter.Advertisement.iBeaconSetAdvertisement(new iBeaconData());

I've published the sample project on GitHub (here is the link ). The solution has 4 projects:
  • Beacons.Helper - UWP library that contains the extension methods
  • Beacons.Universal.Foreground - the sample for the  BluetoothLEAdvertisementWatcher
  • Beacons.Tasks - the runtime component that contains the background tasks
  • Beacons.Universal.Background the sample for register/unregister and monitor a background task that scans for iBeacons
The next blog post will be on configuring the device as an iBeacon. We will look at the new publisher API. 

If you have questions don't hesitate to contact me (you can find me on twitter or email - I have disabled the comments on the blog because there was a lot of SPAM)

I also recommend (if you have time) to watch the Build 2015 session of Kiran Pathakota :  Building Compelling Bluetooth Apps in Windows 10
Hope you've enjoyed the post!

NAMASTE!   

Wednesday, June 10, 2015

Manually install Google Apps on Hyper-V Android emulator

    One of the "hot" new features of Visual Studio 2015 is the new Android Hyper-V emulator. It is an awesome feature as you have a highly performant Android emulator running on the same virtualization engine as the Windows Phone emulator. 
   It is an x86 virtual machine and similar to other Android Virtual machines like Genymotion, Xamarin Android Player the Google applications and services are not installed by default.
     For the other engines they usually support installing Google applications by drag-drop. You just have to download the Google Apps specific for the version of Android your emulator is running (you can download it from here ) and drop the package on the emulator running. For the moment this feature is not supported in the Hyper-V version (might still coming) but you can do it manually with a simple sequence of instructions. 
    
    This is what you need to do:

1. Download the GApps packages specific for the Android version your emulator is running
2. Unzip the file
3. Open an adb command prompt (if you have the Xamarin Tools installed in Visual Studio 2015 open the menu Tools->Android->Android Adb Command Prompt) and navigate where you have unzipped your files and go to the system folder from the archive.
4. Execute this set of commands:
  • adb remount
  • adb shell chmod 777 /system
  • adb push . /system

What this commands do is remount the system partition of the emulator to be writable and pushes the contents of the system folder from the unzipped package to the system folder on the emulator. This is the only things that you have to do. Just wait a little bit and you will see that the emultator starts to install everything needed. You might need to soft reset the Hyper-V emulator to make everything work (you should be actually prompted to login with your Google account). Before pushing the System folder content you can also delete the packages that you are not using.

Let me know if you have problems or if i works via email or twitter (disabled the comments on the blog because of all the SPAM I am getting)

P.S. If the links to the google apps package are not working just copy the package name and paste it in a search engine of you choice and you will easily find a mirror for the package.

Thursday, January 1, 2015

Using the Android Hyper-V Preview with Visual Studio 2013

   Happy New Year to you all! While I am anxiously waiting to know if I will be renewed today as an Microsoft MVP (btw being MVP is an awesome experience, the MVPSummit was a great experience even if I was expecting to see more new things so if you can get involved and try this experience). Still planning to do the post on BLE background agents but there are so many things to write that I have to find time to write it. Hopefully this will happen soon.
    So this small post is all about running the Android Hyper-V Preview Emulator that comes with the Visual Studio 2015 Preview as a stand-alone emulator and use it with your production machine running Visual Studio 2013 and the Xamarin tools. Even if the emulator is still in preview if you are doing Android and Windows Phone development on the same machine you won't have to reboot your machine without Hyper-V support in order to have a decent Android emulator. Strangely Microsoft decided for this preview that the emulator can install only if you have the preview of Visual Studio 2015. In theory you could run the preview along with Visual Studio 2013 but things are not always perfect so many of you will keep two different instances for VS 2013 and the Preview. In oreder to get the emulator work you will still have to install the preview of Visual Studio 2015 on some virtual machine or secondary machine and copy the needed files.
    The method is pretty simple. All you will need to do is to copy the folder "Microsoft Visual Studio Emulator for Android" that is located inside Program Files (x86) [ %PROGRAMFILES(X86)%] folder to the machine you want to run the emulator on. At this point you have everything you need. Copy the folder at the same location on the other machine. We still need to take two steps before launching the emulator for the first time. Inside the folder that you've just copied there are two files vsemu.vhd and sdcard.vhd that will be used to "generate" the two virtual machines (phone and tablet). Here are the two steps that you have to take:
  1.  Make sure that adb.exe is in your Path as it will be used by XDE.exe
  2. Create a new folder called Android inside the folder "%userprofile%\AppData\Local\Microsoft\XDE" and copy the two vhd each of them two times with the following names:
     vsemu.vhd copied as: vsemulator.phone.android.vhd and vsemulator.tablet.android.vhd
     sdcard.vhd copied as vsemulator.phone.android.sdcard.vhd and vsemulator.tablet.android.sdcard.vhd

     Now we are ready to start the emulator. You won't be able to start the emulator from Visual Studio 2013 the way VS 2015 Preview does but you can start it manually and once you've started it and the adb automatically connects to the emulator you will see it in Visual Studio as a deployable device. Let's not mention that you can actually use the accelerometer, the location, battery simulation and the screenshot (awesome).

     Here are the two commands that you need to run (make a batch on your desktop):

Phone Android Emulator:
"%PROGRAMFILES(X86)%\Microsoft Visual Studio Emulator for Android\1.0\XDE.exe" /name "VS Emulator Android - Phone" /vhd %userprofile%\AppData\Local\Microsoft\XDE\Android\vsemulator.phone.android.vhd /video "720x1280" /memsize 1024 /telemetrySession "14.0;eyJBcHBJZCI6MTAwMSwiRGVmYXVsdENvbnRleHRJZCI6ImJkNmMxNjk2LTQ5ZjUtNDI4My1iZTk2LWUzNGNjZWYwZTA4YSIsIkhvc3ROYW1lIjoiRGV2MTQiLCJJZCI6ImIyOWZlODMwLThhOWMtNDE1Yy04MWExLWFlNTFkNzFiYTUwNSIsIklzT3B0ZWRJbiI6dHJ1ZSwiUHJvY2Vzc1N0YXJ0VGltZSI6NjM1NTU2MTAxODUyMjI0MzA1fQ=="

Tablet Android Emulator:
"%PROGRAMFILES(X86)%\Microsoft Visual Studio Emulator for Android\1.0\XDE.exe" /name "VS Emulator Android - Tablet" /vhd %userprofile%\AppData\Local\Microsoft\XDE\Android\vsemulator.tablet.android.vhd /video "1080x1920" /memsize 2048 /telemetrySession "14.0;eyJBcHBJZCI6MTAwMSwiRGVmYXVsdENvbnRleHRJZCI6ImJkNmMxNjk2LTQ5ZjUtNDI4My1iZTk2LWUzNGNjZWYwZTA4YSIsIkhvc3ROYW1lIjoiRGV2MTQiLCJJZCI6ImIyOWZlODMwLThhOWMtNDE1Yy04MWExLWFlNTFkNzFiYTUwNSIsIklzT3B0ZWRJbiI6dHJ1ZSwiUHJvY2Vzc1N0YXJ0VGltZSI6NjM1NTU2MTAxODUyMjI0MzA1fQ==" /noStart

You won't probably need the /telemetrySession but this way you could give back some feedback (I guess). Also the first time you run the emulator it will ask permission to configure the Internet on the device and of course you will have to accept.

Also while digging to make this work I found out that the source code of the Android Preview Emulator is published here:  http://aka.ms/getsource . In the same place there is also the source code for the Microsoft Wireless Display Adapter. It looks like it is running on Linux kernel with a pretty decent CPU and we might get some new features other than a simple Miracast adapter.

Until my next blog post: NAMASTE and again HAVE A GREAT NEW YEAR!






Friday, October 24, 2014

Using Cordova/PhoneGap with Xamarin Android

    Since I haven't found a lot of informations on this matter searching with Google I've decided to share my solution and, maybe, save some time for some of you. The target of this post is to get the Cordova / Phonegap running inside an Xamarin Android project on an Android device.

    In order to use Cordova inside an Xamarin project you would first need to build the Cordova framework.  What I did was to clone the repository Cordova Android and then follow the Building without the Tooling instructions.

      Once you have the cordova*.jar we can start binding the library using Xamarin. Do to that you will have to create a new Project using Xamarin Studio (this does not work in Visual Studio) and select the Android Java Bindings project type:


       The structure of the project is pretty simple. Add the Jar to the Jars folder and ensure the Build action is set to EmbeddedJar and try to build the project.



  You will get some errors compiling but luckily these errors are on components we don't need to bind to. So what you have to to is to edit the Metadata.xml file inside the Transforms folder and add the these two internal packages that we want to ignore:

Doing that will enable to correctly build the binding project.

    Now that we have the binding we can test it. For this I have build a test Project and copied the test www container from the github repository.  It took some while to make it work but everything seems to run as expected. I didn't have time to implement all the activities from the sample but only some of them. It should be pretty easy to port also the others if needed. This sample also uses a custom plugin that launches activities when the button on the main screen get pressed so you should basically have all that you need to start using Cordova with Xamarin. When you launch the project you should see this screen on your device/emulator:



These are the items implemented in the Test project: Backgroundcolor, Basic Authentification, Full Screen, HTML not found, Iframe Lifecycle, Menus & Splashscreen

Here is the link to my Github repository that contains the Binding project and the Test project. This sample is using Cordova 3.7.0


Contact me if you need help

P.S. Still preparing the 3rd post on BLE and it will be the most interesting one as it will be on running in the background.

NAMASTE!





Sunday, June 22, 2014

BLE for developers in Windows 8.1 Part II

      I am sorry that it took me a while to get the second part ready, but better late than ever.
     This second part will be actually about discovering services and characteristics using the new API's available in Windows Phone 8.1 release. As you probably remember this was not possible using the Windows 8.1 BLE API as it is not directly exposed for the store applications. The good news is that things started to move in the right direction with Windows Phone 8.1: possibility to query the services and the characteristics available in a device, support for background tasks and triggers for Bluetooth events, possibility to open the Bluetooth pairing window from inside of our applications (this feature was already available in Windows Phone 8.0 and, luckily, it is still there in 8.1) . There are still some missing features like: 
  • no support real beacon scenario as the user have to manually pair the BLE device before it is accessible to the application
  • no support for server mode. Windows Phone 8.1 supports only client mode
     Hopefully we will see better API in the next release of Windows and at some point the two API's will aliogn. In this moment Windows Phone has better support for BLE devices than it's bigger brother.
     To better illustrate the new API I have created and published an Windows Phone XAML application that is already available in the Store and I've uploaded the source code on Github.
     In order to be able to develop/test for BLE devices you will need and LE device (see the devices from my previous post and since then my collection just got bigger as I've got an Polar H7 heart rate monitor, and the Nokia Treasure Tag) and you will need an Windows Phone 8.1 device that supports the new LE stack. Regarding the device there are good news and a bad news. The good news is that all the Windows Phone 8 devices have hardware that support LE and will support the feature once they will receive the official update. The bad news is that with the Developer Preview this feature is not supported (on the Nokia devices there is an stack conflict between the GDR3 Nokia LE driver and the Microsoft one, Samsung Ativ S it needs a firmware upgrade, and maybe, from what I've heard, it works on the HTC 8x devices but I don't have one and I cannot confirm). So if you have an Windows Phone 8 device you will need to wait for the official release. On the other hand if you have a new Windows Phone 8.1 device like the Lumia 930 or 630 these feature is already supported along with all the other cool features available in the new release . The Lumia 630 and 930 are awesome as they have support for Nokia Sensor Core a technology similar to the one present in the iPhone 5S. The easiest way to see if your device supports LE is to buy an LE device, open the system Bluetooth pairing window and see if you are able to see the device in the list of devices you can pair with.
     In this post I will use the Nokia Treasure Tag. Our goal is to find out as much as we can about the services and characteristics exposed by this device. We will use the new Windows Phone XAML projects available in Visual Studio 2013 Update 2.
     Just like Windows 8 in order to be able to list LE devices from inside of our application we will have to specify in the Package.appxmanifest the type of Device we would like to connect to. As we don't know the services a priory we would choose the a generic service that is implemented in most of the devices and, from my tests, I think Generic Access is a good choice. The lines we will have to manually add inside the Package.appxmanifest are:
 
 <Capabilities>  
   <Capability Name="internetClientServer" />  
   <m2:DeviceCapability Name="bluetooth.genericAttributeProfile">  
    <m2:Device Id="any">  
     <m2:Function Type="name:genericAccess" />  
    </m2:Device>  
   </m2:DeviceCapability>  
  </Capabilities>  

   Then just like in Windows 8.1 we can enumerate the paired devices using DeviceInformation.FindAllAsync and use the predefined GenericAccess UUID:

  bleDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(GattServiceUuids.GenericAccess));  

     The output of this method is a DeviceInformationCollection of paired devices that expose the Generic Access service.
     If no devices were found that exposes this service it means that no device was paired with our phone or the Bluetooth is disabled on the device. In this case we can easily open the Bluetooth settings window:
 Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-bluetooth:", UriKind.RelativeOrAbsolute));  
     Once we have the devices we can select one of them and create a new instance of the newly added class in Windows Phone 8.1 SDK BluetoothLEDevice. This class can be usedto enumerate all the services available on the device. If you look at the description of the class you will see that it is only supported on Windows Phone (no support for Windows Store applications). We will use the Id property available inside the DeviceInformation to instantiate the class.
  BluetoothLEDevice _device = await BluetoothLEDevice.FromIdAsync(((DeviceInformation)e.Parameter).Id);  
     The BluetoothLEDevice exposes a property called GatServices of type IReadOnlyList<GattDeviceService>  that will give us the list of all the services available on the device. GetDeviceService is a class that is already implemented in Windows 8.1 but it was extended on Windows Phone 8.1. To get a friendly name of the device service (not only the Guid) you could use reflection, but I have created a helper class BLEHelper.cs (see the github project) that can be easily extended to cover more known services. Remember that all the LE services that have an id that start with 000018 and end with -0000-1000-8000-00805f9b34fb are probably standard LE services and you can find further details about them here.

     Once we've identified the service we are interested in (we have an instance of the class) we will use the newly added method GetAllCharacteristics() (another method available only for Windows Phone) to get the list of all the characteristics the services exposes and for each characteristic we can get its properties, values, type,....

     Each characteristic have an unique id and, int his case, for mapping the Guid to a known name on the UI I have created a simple converter that uses reflection to search and map the Guid to a GattCharacteristicUuids name:

 public class CharacteristicName : DependencyObject, IValueConverter  
   {  
     public object Convert(object value, Type targetType, object parameter, string language)  
     {  
       if (value != null && (value.GetType() == typeof(GattCharacteristic)))  
       {  
         var c = (GattCharacteristic)value;  
         if (c.UserDescription != "")  
           return c.UserDescription;  
         foreach (var prop in typeof(GattCharacteristicUuids).GetRuntimeProperties())  
         {  
           object v = prop.GetValue(null);  
           if (v != null && v.GetType() == typeof(Guid) && ((Guid)v) == c.Uuid)  
             return prop.Name;  
         }  
       }  
       return "Unknown";  
     }  
     public object ConvertBack(object value, Type targetType, object parameter, string language)  
     {  
       throw new NotImplementedException();  
     }  
   }  

     If you download the BLEExplorer app you can also use share to export all  the data (services+characteristics) to any application that support text sharing (like email).
     In the next post I will explain how to create background tasks that subscribe notifications from an BLE device, manage connection lost and reconnect in the backgroun.

P.S. If you have questions please do contact me by email and I will be glad to help. I have disabled the comments on the blog because there was a huge amount of Spam.

NAMASTE!