Thursday 3 January 2013

USB Dongles and Serial Ports in .Net

I have spent the past three years working on mobile field applications for Centrica, mainly on the Smart Metering team.  One of the challenges we faced was with the use of USB dongles that create serial ports.  In our application we used a Zigbee USB dongle manufactured by Telegesis.  This dongle would be attached to a Panasonic H1 Toughbook and the Smart Energy Expert would proceed to commission/decommission smart devices.  Due to the design of the H1, the USB dongle would inevitably get knocked off abruptly terminating the serial port communications.
If you are reading this article you are probably familiar with the well-documented Serial Port issues in the .Net framework.  Many in the .Net community have declared .Net's Serial Port support to be unreliable at best.
In the above scenario, you will become aware of the removed USB dongle when you attempt to read or write data to the serial port - the serial port that no longer exists.  Unfortunately this is not a case where you simply wrap your code in a try/catch and you're good to go.  What you will likely experience are Windows IO exceptions or Dispose exceptions.  When these occur your application cannot recover from them, nor can you trap these exceptions.
Zach Saw has written an excellent blog on this type of scenario here. While this proposed solution goes a long way to resolving this situation, we were still getting unpredictable (and unrecoverable) exceptions.  I have to admit this was a tough nut.
In my research I stumbled upon an MSDN article written by John Hind entitled Use P/Invoke to Develop a .NET Base Class Library for Serial Device Communications written in October 2002.  For all you .Net historians, you might recall that SerialPort support in .Net did not appear until version 2.0.  So, here was John effectively rolling his own using Win32.  A brave soul.
Could it be that a 10 year old piece of code held the answer to our problem?  At this point I was willing to try anything.  Something about it made sense.  This approach removes Microsoft's dodgy SerialPort implementation and relies on the much more stable Win32.  Implementing John's code into our project took a bit of finesse, but we got there and it worked beautifully!
Since finishing up at Centrica I've had some time to put together a sample solution which implements John's code (with changed naming conventions and formatting) and includes a simple Zigbee Test application.

The sample uses WMI to detect the removal/insertion of the USB dongle (there are other ways to do this).  And utilises the custom Serial Port from John Hind.  You can download the solution here (ZigbeeUSB.zip).

1 comment:

Unknown said...

Nowadays it become very easy to buy a dongle in India. We can use the online shopping to purchase the data cards with ease and affordable prices.