<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Holger Kenn</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/holgerkenn/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/holgerkenn/feed.xml</link>
    <description>Smart things and the cloud</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:10:24 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>When you cannot use Azure IoT Device Provisioning Service</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/when-you-cannot-use-azure-iot-device-provisioning-service</link>
      <pubDate>Mon, 16 Jul 2018 11:00:03 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/?p=215</guid>
      <description><![CDATA[Hi!

You may know already about the Azure IoT Device Provisioning service, if not, head to...]]></description>
      <content:encoded><![CDATA[Hi!

You may know already about the Azure IoT Device Provisioning service, if not, head to <a href="https://docs.microsoft.com/en-us/azure/iot-dps/">https://docs.microsoft.com/en-us/azure/iot-dps/</a> for more information.

The idea behind DPS is short and simple: Imagine, you're the manufacturer of an IoT device and you want enable your device to "just work" once it's delivered to your customer. So the customer unpacks the device, plugs in Ethernet and the device lights up, starts talking to the cloud, receives device configuration information. So far, so easy, you think, in production, let's just provision an Azure IoT hub device connection string or a x.509 certificate and that's all.

So why would you need DPS? Let's say your device has been configured at the factory, but it's been sitting on a shelf for years. And then it gets exported to a country where you never thought you would sell devices to, back in the days when you created your service. That's when you decided that you would use a x.509 certificate and a single iot hub. But now, a couple of years later, you have 10 iot hubs in different geographies and the initial certificates you installed in the device have expired since you set their validity to 3 years. This is where DPS comes in. Your device can now go to the global DPS endpoint and ask: "is there a new configuration for me?". DPS now looks through its database to find a matching configuration. If it does, it encrypts it in a way that only this particular device can decrypt the information and sends it back to the device. The device then decrypts the configuration information using its built-in hardware security module and in it, it finds the configuration for an iot hub. It then connects with the obtained credentials, receives additional configuration information such as OS and application update instructions and suddenly works. Your customer is delighted and you are too since you now have another device talking to your backend service.

So why wouldn't you do this all the time? Well, there is one important prerequisite for using DPS: You need to add a device-individual public/private key pair to the device at production time and you need to record the public key in a secure way at this time (or install a certificate used for group registration to be precise). Doing so isn't very hard (e.g. if your devices have a built-in TPM 2.0, you can just use the built-in "EK" of the TPM for this) but the HSM adds BOM cost and reading out the information adds time in the manufacturing process.

Now imagine, you have a very simple device such as the teXXmo IoT Button (<a href="http://www.iot-button.eu/">http://www.iot-button.eu/</a>) which does not have a HSM, but needs an Azure IoT Hub device connection string. You can now go back to the initial approach and provision every device with an individual connection string at production. But maybe you don't want to give your manufacturer full access to your production IoT hub when provisioning devices, but you still need an automated way to generate these connection strings.

This is where my simple <a href="https://github.com/holgerkenn/qdrs">Quick Device Registration Service</a> sample comes handy. (Or did somebody say Quick &amp; Dirty Registration Service?) Instead of handing over the keys to the castle (i.e. the iot hub owner connection string) you install this service as an Azure function and provide your manufacturer with the access codes to this service and he can produce device-individual iot hub connection strings while producing devices. The sample client included in the solution calls the service with a given device serial number and gets back the iot hub connection string for this device. The service also checks that no serial number is used twice and that each serial number is valid. (In the sample, it just checks if a serial number is divisible by 7, but you can test in whatever way you can imagine, e.g. CRCs, min/max etc.) Once the manufacturer has obtained the device connection string, he can write it into the device. Once the device is connected to the Internet, it has all information necessary to talk to your Azure IoT Hub.

But there is another usage for this. Imagine you want to use IoT hub in a software-only product, let's say a digital signage solution that is "just" an application that an end user can install on an existing PC. Or it's a driver package that comes with your device, and the device is a PC peripheral that does not talk to the cloud directly. In both cases, there is no factory provisioning possible. And while there may be a device-individual identity (e.g. a device serial number) you may not have any space to store (let alone secure) a per-device secret. But you still want to use IoT hub since it's such a neat way to get information from your device, send information from the cloud to the individual devices and manage your devices using the device twin.

So you add code to your application or driver stack that calls the registration service during installation. The code reads out the serial number information (or even asks the user to enter it?) and then calls the service to obtain the device-individual connection string. It then stores the string locally (let's say in a configuration file on disk or in the Windows registry) and then uses it to connect to an IoT Hub.

But here, a word of warning is required: If you implement such a solution, the credentials used to call your registration service need to be in your client application or driver stack. So, if there is information, it can be found using reverse engineering. Still, this is better than leaving the IOT hub owner credentials in the client application or, even worse, leaving behind a signing key that would be able to create valid group registration certificates for DPS. Nevertheless, you should implement some protection against reverse engineering and monitor your registration service carefully to identify potential attackers that may have found the credentials and try to compromise your service.

If you need a secure solution, use DPS (and a hardware security module!) If you can't, then have a look at <a href="https://github.com/holgerkenn/qdrs">https://github.com/holgerkenn/qdrs</a> and see if it fits your need.

Hope this helps,

H.

&nbsp;

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Mioty at DPK</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/mioty-at-dpk</link>
      <pubDate>Tue, 21 Nov 2017 16:51:50 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/?p=196</guid>
      <description><![CDATA[Hi!

A couple of weeks ago, we had the Microsoft German partner conference (DPK) in Leipzig, where...]]></description>
      <content:encoded><![CDATA[Hi!

A couple of weeks ago, we had the Microsoft German partner conference (DPK) in Leipzig, where our IoT partners were showing their solutions. And one of the partners that presented their technology is <a href="http://mioty-iot.com/">Mioty</a>.

So what is this? (roll <a href="https://www.youtube.com/watch?v=FZ5GYeZJS3k">video</a> )

Mioty is a LPWAN technology that adresses shortcomings that we have seen with the existing technologies in this area. With Mioty, we have found something that works for scenarios where we need long range and lots of sensors. And for places where it will take a very long time for traditional telco infrastructure to build up coverage.

Like many other LPWAN technologies, Mioty operates in the license-free bands, depending on the geographic region it is deployed in it will use 868 or 915 Mhz. The good thing about these bands is that the penetration into buildings is much better than in the higher 2.4 Ghz bands. So we have seen examples where Mioty has been used in mines and worked in places where even conventional two-way radio would not work reliably. So that's pretty good. It's not intended to send around gigabytes of data, but it can process more than one million sensor messages per day over its full range of around 15km in free space and 5km in city areas.

The people behind Mioty are from the same research institute that brought you things like the digital radio standard DAB and, as a little side project thereof, "Adaptive Spectral Perceptual Entropy Coding", an audio codec technology better known under its standardization name "MPEG-1 Audio Layer III" or the file extension used for encoded audio files. "mp3". Mioty has been developed by the Fraunhofer Institute for Integrated Circuits (<a href="https://www.iis.fraunhofer.de/en.html">Fraunhofer IIS</a>).

So about one year ago, I met one of the people behind this, Albert Behr from Behr Technologies at a Fraunhofer Event here in Munich. One of the event organizers grabbed me by the arm and almost pulled me across the room, saying "I have someone you have to meet." We met, we talked for a while and I thought "That this is a really interesting technology, but I'd like to see it working first". Having spent my time in academia, I was well aware of the different goals people in Academia and Industry have, knowing the "Publish or perish" situation all to well and understanding that moving from paper to product is often not rewarded in academia. But Fraunhofer, being a group of applied research institutes that have a track record of moving research results into products and standards, and IIS in particular being behind this added credibility to his claim and we decided to keep talking and see where this leads us. And so he introduced me to the leads of the Fraunhofer working groups behind the technology, Günter Rohmer and Michael Schlicht as well as Wolfgang Thieme who is driving the business development. We received a test kit, played around with it and worked with the Mioty development team to hook it up to Azure IoT. We have helped them build a solution that allows Mioty to gather data from all the sensors, send the data up to the cloud and make it available to any Azure cloud service, either in the form of a near real-time data stream or stored in a database.

Albert and Wolfgang have since approached more than 20 early adopters from various application areas with this technology and have received very positive feedback. And for me, it has been great to work with the Mioty team to push the limits of LPWAN and to enable a whole new set of customers and applications to link their sensors to Azure IoT.

I can't wait to see where the Mioty team will take this.

H.]]></content:encoded>
    </item>
    <item>
      <title>Hilscher NetPi: Raspberry Pi 3 for industrial automation (Part 1)</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/hilscher-netpi-raspberry-pi-3-for-industrial-automation-part-1</link>
      <pubDate>Mon, 30 Oct 2017 12:25:54 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/?p=166</guid>
      <description><![CDATA[Hi!

Over the last weeks, I've been working with a nice little device that is very useful for...]]></description>
      <content:encoded><![CDATA[Hi!

Over the last weeks, I've been working with a nice little device that is very useful for prototyping professional IoT.

One of the challenges in this area is talking to field bus systems. There are many field busses out there and all of them have their individual reason of existence, either coming from a specific group of hardware vendors (e.g. Profibus and Profinet coming from the Siemens PLC ecosystem) or being adopted in specific application domains (CAN in vehicles). But luckily, there are companies that have implemented hardware and software to talk to many of these busses and <a href="http://www.hilscher.com/">Hilscher</a>  is one of those partners. They have implemented their own silicon in form of their NetX chip which is able to speak many of these protocols.

Now enter the <a href="https://www.netiot.com/industrial-raspberry-pi-3/netpi/">NetPI</a>. Hilscher has built an industrial gateway hardware that combines the standard Raspberry Pi 3 Broadcom SOC with a NetX chip. In addition, they took some ideas from the RPi 3 compute module and added an eMMC to replace the ever-failing SD-cards and added a standard 24V industrial grade power supply circuit.

On the software side, the NetPI runs a hardened Linux, Docker and a web-based UI. Via this UI, one can run Docker containers. See <a href="https://hub.docker.com/r/hilschernetpi/">here</a> for a list of images provided by Hilscher.

Getting the device up and running is rather straightforward:

Attach Ethernet and 24V (my device is drawing 150 mA, so about 3.6W). The NetPI will do dhcp on its Ethernet port and acquire an IP address. It will also register a hostname which is simply "NT" plus its Ethernet address, that's all printed on its side. Now you can access your device via http://NTxxxxxxxxxxxx or via its IP address http://x.x.x.x that you can find in your router. It will redirect you to https:// and then you will see a certificate warning. Ignore the warning and connect anyway. (In Edge on Windows 10, you need to click on "Details", then "go on to the website". You can upload a certificate to the device, then this error goes away.) Then you will see this:

<img width="300" height="88" class="size-medium wp-image-176 aligncenter" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/10/HilscherNetPi1-300x88.png" />Here, you can configure the device via the "control panel" or manage Docker. The initial login information is printed on the side as well. (No big secret here: username "admin", password "admin", the device will force you to change the password immediately.) To make things work, you should first check if the clock is set right in the control panel, otherwise you will get a number of strange errors, but their root cause is that the NetPI does not accept any TLS certificates because it thinks they are outside their validity period. So click on control panel, (accept the certificate warnings again) then log in and head to system/time. Now add an NTP server of your preference (I'm using ptbtime1.ptb.de which is the official master clock in Germany) and press "save changes".  Now the clock should update and under "status", the display should read "Synchronized to time server ..." <strong>If you don't do this step, there is a high chance that you won't be able to run any Docker images since the TLS-based download of the images will fail!</strong>

Now click on the Services/Service List in the menu, then select Docker. Start Docker and set the Docker service to autostart, then click "Apply".

Now head back to the main portal and this time, click on Docker. The quickest way I found is simply to edit the URL and remove anything behind the host name. If you have successfully started Docker, then you will get to the Docker management interface when clicking on the item. If not, then head back to the Service menu and check if Docker is running (the icon next to Docker should be green.) Now you should see the portainer.io Docker management portal. To check if the internet connection is working, go to the "image" section and enter "hilschernetpi/netpi-raspbian:latest" in the Name field under "Pull Image" and click "Pull". Now the image should show up in the image list below. Other useful images to pull are "hilschernetpi/netpi-nodered-fieldbus:latest" and "hilschernetpi/netpi-netx-programming-examples:latest".

To get started, run the Node-RED fieldbus container on your device. The instructions are <a href="https://hub.docker.com/r/hilschernetpi/netpi-nodered-fieldbus/">here</a>. If you want to write code that interacts with the fieldbus directly, look <a href="https://hub.docker.com/r/hilschernetpi/netpi-netx-programming-examples/">here</a>. This environment can also be used to run the Azure IoT SDK on the NetPi. I will write up more instructions on this in my next post.

Hope this helps,
H.

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Just returning from ISWC2017</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/just-returning-from-iswc2017</link>
      <pubDate>Sat, 16 Sep 2017 17:20:05 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/?p=165</guid>
      <description><![CDATA[Hi!

I'm on my way back from ISWC2017 (the International Symposium on Wearable Computing) and it's...]]></description>
      <content:encoded><![CDATA[Hi!

I'm on my way back from ISWC2017 (the International Symposium on Wearable Computing) and it's been great! This year marks ISWC's 20th anniversary. The web page of the first conference can now only be found on the wayback machine: <a href="https://web.archive.org/web/19981203153100/http://iswc.gatech.edu/wearcon97/default.htm">ISWC '97</a>

This year, I was organizing the industry session at ISWC and Ubicomp and we had great talks of people from industry that don't get to talk to the academic world that often. Including myself...
<div id="body-wrapper"><section>
<div class="container clearfix" id="content">
<div class="post single clearfix">
<div class="post-entry program">
<ul class="post-meta">
 	<li class="title">Activity Recognition at Google: Building and Deploying for a Billion Android Devices
<ul>
 	<li class="author">Jennifer Wang, Google</li>
</ul>
</li>
 	<li class="title">Embracing Human Individuality in Wearable Computing Design
<ul>
 	<li class="author">Matthew Bailey, Stefan Alexander, Thalmic Labs</li>
</ul>
</li>
 	<li class="title">Gepetto's workshop - Designing and Creating for Humans
<ul>
 	<li class="author">Bruce Bradtmiller, AnthroTech, Diane Elabidi, Google</li>
</ul>
</li>
 	<li class="author">Optical architecture of HoloLens MR headset and hardware challenges for mass adoption
<ul>
 	<li class="author">Bernard Kress, Microsoft</li>
</ul>
</li>
 	<li class="author">Digital Reality with Microsoft devices and Mixed Reality platform
<ul>
 	<li class="author">Christian Waha, Industrial Holographics</li>
</ul>
</li>
 	<li class="author">Design of a wearable device for professional applications
<ul>
 	<li class="author">Holger Kenn, Microsoft</li>
</ul>
</li>
</ul>
I'm planning to have their presentations up in a few days, either here or on a separate website.

For information on the conferences, go to the <a href="http://ubicomp.org/ubicomp2017/">Ubicomp</a> and <a href="http://iswc.net/iswc17/">ISWC</a> websites.

H.
<div id="body-wrapper"><section>
<div class="container clearfix" id="content">
<div class="post single clearfix">
<div class="post-entry program"></div>
</div>
</div>
</section></div>
</div>
</div>
</div>
</section></div>]]></content:encoded>
    </item>
    <item>
      <title>Pi-Top and Windows 10 IoT Core: A Raspberry Pi Laptop running Windows</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/pi-top-and-windows-10-iot-core-a-raspberry-pi-laptop-running-windows</link>
      <pubDate>Fri, 25 Nov 2016 09:29:09 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/?p=125</guid>
      <description><![CDATA[Hi!

I'm in the middle of preparing a hands-on lab for an event next month, Microsoft Germany's...]]></description>
      <content:encoded><![CDATA[Hi!

I'm in the middle of preparing a hands-on lab for an event next month, <a href="https://www.microsoft.com/germany/technical-summit/">Microsoft Germany's Technical Summit in Darmstadt</a>. Here, we will show you how to build, customize, program and connect devices based on Windows 10 IoT. And for this hands-on lab, we decided to bring a couple of Raspberry Pi 3 to play around with.

In order to get the full benefit of Windows 10 IoT Core including its ability to run full UWP apps, you need a screen, mouse and keyboard. So I was looking for a nice package that includes all this, and I found the <a href="https://www.pi-top.com/">Pi-Top</a>. This is essentially a notebook housing kit including power supply logic, touchpad, keyboard and screen, only lacking a Raspberry Pi and a bit of your time to turn it into a nice little notebook computer.

The remaining question was just: Would it run Windows 10 IoT Core? And yes, it does!

<a href="https://msdnshared.blob.core.windows.net/media/2016/11/Pi-Top-running-Windows-10-IoT.jpg"><img width="300" height="225" class="alignnone size-medium wp-image-145" alt="pi-top-running-windows-10-iot" src="https://msdnshared.blob.core.windows.net/media/2016/11/Pi-Top-running-Windows-10-IoT-300x225.jpg" /></a>

The Pi-Top keyboard and touchpad are connected via USB, they work right out of the box, so does the built-in screen. The Pi-Top-Hub (in the picture on the left) powers the display and the Pi and converts the HDMI output of the PI to the signals needed by the display. It also controls the charging of the built-in battery and the screen brightness, even when it's not connected to the Pi.

When it is connected to the pi, there's a bit of randomness in the startup process. Occasionally, the Pi-Top hub gets some signals from the Pi, probably during initialization of the SPI ports, that it misinterprets as a screen brightness or power control command. In the worst case, this just cuts the power and the PI crashes. So right now the "safe" way of operating is not to plug in the cable connecting the pi-top-hub to the IO connector of the Pi.

But if it's connected, then you can use the Windows.Devices.SPI api in Windows 10 IoT Core to control the Pi-Top hub, e.g. to control the screen brightness, to detect the power button press or the lid closure or monitor the battery. I'm still working on a sample that I will put on github once it's ready.

H.

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Troubleshooting Azure IOT Hub connections on embedded Linux</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/troubleshooting-azure-iot-hub-connections-on-embedded-linux</link>
      <pubDate>Wed, 10 Aug 2016 02:13:35 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/?p=115</guid>
      <description><![CDATA[Hi!

I'm in Japan for a few days, working with local partners to get their devices connections to...]]></description>
      <content:encoded><![CDATA[Hi!

I'm in Japan for a few days, working with local partners to get their devices connections to Azure IoT Hub. And I want to share a few lessons learned.

We always started from the <a href="https://github.com/Azure/azure-iot-sdks/">Azure IOT Hub SDK on GitHub</a>.  And here's the first catch: if you just download the zip file from GitHub, you are missing the links to other dependent projects and your source tree is lacking some files. To avoid running into these problems, please clone the project using git and don't forget to add the --recursive option as described <a href="https://github.com/Azure/azure-iot-sdks/blob/master/c/doc/devbox_setup.md">here</a>.

git clone --recursive https://github.com/Azure/azure-iot-sdks.git

In case you get strange compiler errors on the way, such as mismatch of function signatures, it might be that your source tree is out of sync. One way to fix this is to run "git submodule init" and "git submodule update" in the right directories, but I often just throw away the whole tree and clone it again.

The first thing you should do is to familiarize yourself with the SDK on a normal Linux machine. For this purpose, I just run a Linux VM on Azure. Go through the steps of setting up the development environment and setting up an IoT hub, just for testing. The free tier of the Azure IoT Hub is sufficient at this point. Now create a device ID in your IoT Hub, e.g., by using the <a href="https://github.com/Azure/azure-iot-sdks/tree/master/tools/DeviceExplorer">Azure IoT HubDevice Explorer </a>on Windows. Under the management tab, select your created device and then right-click and select "Copy connection string".

Go to the source code of one of the simple examples, e.g., <a href="https://github.com/Azure/azure-iot-sdks/tree/master/c/iothub_client/samples/iothub_client_sample_amqp">the C amqp sample client</a>. Insert your connection string in the source code and compile the sample. Now head back to the device explorer, click on the data tab and start monitoring data from your device. Then run the sample client executable. You should now see a few messages arriving. Now in device explorer, switch to the "Message to Device" tab, select your device and enable "Monitor Feedback endpoint". Now type something in the message field and hit send. Your sample client should receive data and the feedback endpoint monitoring should indicate that the messages have been received.

Great, now let's move over to the actual device!

Here, there are a couple of things you need to be aware of, the two most important ones are trust and time. Wait? What? Is this some relationship self-help blog? :-)

The trust issue:

Unfortunately, some embedded devices do not come with the right set of certificate authorities installed. When the Azure IOT SDK client code tries to establish a secure connection, it validates the certificate presented by the IOT hub against the known certificate authorities. If there is none, the client code stays quiet for a very long time and then fails with various errors. In order to test for this condition, I often just use the openssl client program and try to establish the connection manually from the device.  Most embedded Linux distributions have the openssl executable installed together with the openssl library. An alternative is to run both the sample and "tcpdump -w capture.pcap" at the same time on the device, then download the pcap file and analyze it using <a href="http://www.wireshark.org/">wireshark</a>.

For example, if I want to see if I can reach the mqtt endpoint of my IOT Hub, I run the following command:

openssl s_client -connect &lt;My iothub name&gt;.azure-devices.net:8883

(and of course replace &lt;&gt; with the name of your IOT hub)

If this command fails to establish a valid TLS connection with "Verify return code: 20", you have "trust issues". If you see "Verify return code: 0 (ok)" then everything is OK. In wireshark, you would see the TLS negotiation fail with "No CA".

To resolve your trust issue, make sure the right CA certificate is present on the device. Microsoft uses the Baltimore CyberTrust CA to sign the server keys, so you should have the file "Baltimore_CyberTrust_Root.pem" somewhere in your file system. But even if it is there, the openssl library may not load it. To find out where it expects the files to be, just run "openssl version -d". You should see something like this:

OPENSSLDIR: "/usr/lib/ssl"

This means that the OpenSSL library will look for the CA cert in the file /usr/lib/ssl/cert.pem and then in files in the directory /usr/lib/ssl/certs/

But it may be that the file is actually there but OpenSSL still fails to establish a secure connection. Then you might have a time issue.

The time issue:

CA certificates have a time span in which they are valid. For instance, the Baltimore CyberTrust CA openssl x509 is valid in the following time span:

Not Before: May 12 18:46:00 2000 GMT
Not After : May 12 23:59:00 2025 GMT

You can easily check for yourself by running this command:

openssl x509 -in /usr/lib/ssl/certs/Baltimore_CyberTrust_Root.pem -text

How could this be invalid? Easy: Some embedded devices have no battery-buffered realtime clock and initialize their clocks with preset dates on boot. And these may be ancient, e.g. Unix Epoch (January 1st, 1970), GPS epoch (January 6th, 1980) or whatever the manufacturer set. So a good practice is to set the clock to the right date before attempting to connect.

But that might not be enough.

The Azure IOT hub also uses a time-based token scheme to authenticate its clients. The process is described <a href="https://azure.microsoft.com/en-gb/documentation/articles/iot-hub-sas-tokens/">here</a>. The token includes an expiry time as seconds since Unix Epoch in UTC. The Azure IOT SDK uses the device connection string to create such an shared access signature token. If your clock is off, the token created may already have expired. The tokens are generated with a validity of 3600 seconds, i.e., one hour. If your clock is late by more than that, the IOT hub will reject the connection.

So the best practice is to run ntpclient or ntpd on your embedded device. Even busybox has a simple ntpd implementation, so this should be available on your embedded os. Alternatives are of course to use GPS, a mobile network, a battery-powered RTC or a radio time receiver (FM RDS, long-wave time signals etc.) as a time source. But be aware of the startup and initialization times these time sources take (gps can take several minutes to give a proper time information) and the skew RTCs might accumulate over time. And RTC batteries might die after a couple of years. Also make sure that your time zone is properly set, the SDK will always calculate in UTC times, but if your timezone claims to be UTC but the clock is set to the local time zone, you might be off by a couple of hours.

Which brings me back to the CA cert validity. Today, 2025 seems to be far out in the future, but remember that many embedded devices designed today have a lifetime of over 10 years. So that CA cert will expire in the lifetime of these devices. So make sure you have a way to update the CA certificate.

Hope this helps,

H.

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Asia Tour: June 2016</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/asia-tour-june-2016</link>
      <pubDate>Fri, 20 May 2016 02:53:28 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/?p=105</guid>
      <description><![CDATA[Hi!

I'm on the way back from touring partners customers in Taiwan, South Korea and Japan. We had...]]></description>
      <content:encoded><![CDATA[Hi!

I'm on the way back from touring partners customers in Taiwan, South Korea and Japan. We had very interesting meetings with our partners there who are ready to get "things" connected to the cloud. In this post, I want to elaborate on the questions that were most common and how I answered them.
<ul>
	<li>What if my device isn't supported by the Azure IOT SDK? Can you please add support for device XXX, OS YYY and CPU ZZZ?</li>
</ul>
The Azure IOT SDK on GitHub <a title="Azure IoT SDK" href="https://github.com/Azure/azure-iot-sdks">https://github.com/Azure/azure-iot-sdks</a> is already supporting many different device and operating system combination, but given the large number of possible combinations (including legacy devices that still need to be connected) this cannot cover everything. However, it is not required to use our SDK, it's just there to make things easier for you and to get a head start.

So what if my device or OS isn't on the compatibility list <a title="OS platformsn and hardware compatibility list for the Device SDK" href="https://azure.microsoft.com/en-us/documentation/articles/iot-hub-tested-configurations/">https://azure.microsoft.com/en-us/documentation/articles/iot-hub-tested-configurations/</a>? Maybe the SDK actually works! If you have a Windows device that supports the .net Framework Version 4.5, this should be sufficient to run the C#-Versions. If you have a Linux-based OS, the C-version should work as long as you have a fairly recent GCC and OpenSSL version. The Java SE and Node versions should work on most underlying OS platforms that these runtimes support. So maybe you're actually done.

But what if there's a feature missing in my underlying platform, e.g. it does not support TLS1.2 that seems to be required for the SHA256 requirement? Technically, the SHA256 is required to generate a shared access signature from the device key you configure in IOT Hub for your device. But nothing keeps you from pre-computing a shared access signature with a long validity somewhere else and install it on the device. Maybe you could even implement a service that the device can connect to occasionally to request a new signature. (I actually have some code for this as part of my Azure IOT hub proxy I've explained <a title="AzureIotHubProxy" href="https://blogs.msdn.microsoft.com/holgerkenn/2016/02/26/azureiothubproxy/">here</a>,  but that's for another post.)

As an alternative, you could use an additional SSL library such as <a title="OpenSSL" href="https://www.openssl.org/">OpenSSL</a> or <a title="wolfSSL" href="https://www.wolfssl.com/wolfSSL/Home.html">wolfSSL</a> to implement TLS1.2 and SHA256, the IOT SDK has the ability to link to these libraries. This would work independently of the crypto functions provided by your existing OS.
<ul>
	<li>Can I use IOT Hub to manage my devices?</li>
</ul>
And I usually reply to this with another question: What is it you want to manage?

When you think about device management from an IT perspective, there is a common device management definition and there are plenty of solutions to address this. In this area, management means managing OS and application installation and updates, monitoring device usage and applying policy-based restrictions to the devices under management.

In IOT, it might be all of the above, a subset or none of the above.

For IOT devices, it is uncommon to re-install an operating system via device management. Instead, devices are often just replaced when they fail or reach their end of life. Even updates are managed more carefully, and there are still devices out there that never received an OS update in their entire device life. I'm not recommending this practice since the era of unconnected devices is essentially over and anything that's connected can be attacked in some form, so implementing update mechanisms is more important than ever.

Monitoring devices is often very application specific in IOT and it's often more a stream of events sent by the devices than common monitoring task such as the status of the antivirus software installed.

And although device policies exist also on embedded devices, they hardly change over the lifetime of the device.

So a full-fledged IT device management solution might be too much.

But as IOT hub provides a cloud to device messaging channel, that might be just enough to implement a simple, custom device management solution.

In addition, there is a preview of device management functions in IOT hub, but that will be another blog post soon.

&nbsp;

Hope this helps,

H.

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>AzureIotHubProxy</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/azureiothubproxy</link>
      <pubDate>Fri, 26 Feb 2016 05:59:42 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/2016/02/26/azureiothubproxy/</guid>
      <description><![CDATA[Today, I uploaded a project to github that I wrote in the last weeks in order to simplify things...]]></description>
      <content:encoded><![CDATA[Today, I uploaded a project to github that I wrote in the last weeks in order to simplify things with the Azure IoT hub for demos, makers etc.

If you haven't heard about Azure IoT hub, this is a very nice service you can use to hook up your IoT devices to a central service that you can use to receive data, send commands and, in general, manage your devices.

<a href="https://azure.microsoft.com/en-us/documentation/services/iot-hub/">https://azure.microsoft.com/en-us/documentation/services/iot-hub/</a> is the official starting point for the documentation, but basically, the Azure IoT hub has a device and a service API. Through the device api, you can basically send messages to the cloud and receive messages from the cloud. The cool thing about this is that the device side only does outbound connections (e.g. this works through firewalls, through NAT devices such as DSL routers and even through IP connections provided by mobile phone providers. Read this again: Back channel <span style="text-decoration: underline">to</span> your device works through <strong>mobile phone network</strong>!

And the best thing: This service incudes a free tier that allows you to register 500 devices and send 8.000 Messages of 0.5k per day. See here <a href="https://azure.microsoft.com/en-us/pricing/details/iot-hub/">https://azure.microsoft.com/en-us/pricing/details/iot-hub/</a> for details.

But in order to get to all this goodness, you need to manage the IOT hub via its service API. You can do that through the Device Explorer tool (see <a href="https://github.com/Azure/azure-iot-sdks/tree/master/tools/DeviceExplorer">https://github.com/Azure/azure-iot-sdks/tree/master/tools/DeviceExplorer</a> ) but that's a manual process that involves creating devices on the hub and then copying the device connection strings manually into the device configuration. Or you can deal with the standard management API which is a bit tricky to use and actually would require you to keep the management keys where ever you would like to manage it.

Wouldn't it be nice if the devices could actually manage themselves?

So I wrote a little API Proxy service that the device can query to get a connection string. The service just implements four calls.

GET /api/Device get just returns the list of devices configured in a JSON form

GET /api/Device/(id) returns the JSON just for this device

POST /api/Device/(id) creates a new device in the IOT hub and returns a JSON that includes a connection string

DELETE /api/Device/(id) deletes the device in the IOT hub.

In order to secure these, they all require an API key send in the query string.

The implementation I made is really simple and not very secure. But it can be used as a starting point to think about more complex authentication schemes, e.g. one could implement a one-time token mechanism that would only allow a single device registration for each token.

To try out the implementation, I added a swagger interface, so if you go to /swagger/ you can play around with the API yourself. You should disable that for production use.

The service can easily be run in an Azure Web App. And again, there is a free tier that is sufficient to run this service. See here <a href="https://azure.microsoft.com/en-us/pricing/details/app-service/">https://azure.microsoft.com/en-us/pricing/details/app-service/</a> Azure app services also support SSL that you should use in order to protect your API key. (SSL is not supported for custom domains, in the free tier so your website will all end on "azurewebsites.net")

To get started, clone the project from github <a href="https://github.com/holgerkenn/AzureIotHubProxy">https://github.com/holgerkenn/AzureIotHubProxy</a> and then go to <a href="https://azure.microsoft.com/free/">https://azure.microsoft.com/free/</a> to start a free trial on azure in case you don't have a subscription yet. Through this link, you will also get some free credit to use the paid azure services for a limited time, but since everything presented here also works on the free tiers of the services, you can actually run all this even after the free trial credits expire.

Go to <a href="https://azure.microsoft.com/en-us/develop/iot/">https://azure.microsoft.com/en-us/develop/iot/</a> to see how to create your first IoT hub, then get its connection string from the Azure Portal and add it to the web.config file in the repository. Then create a web app on Azure as explained here <a href="https://azure.microsoft.com/en-us/documentation/services/app-service/web/">https://azure.microsoft.com/en-us/documentation/services/app-service/web/</a> and publish the service to this app. In Visual Studio, this is as simple as right-clicking the project, selecting publish and then "Microsoft Azure App Service". This will then guide you to select or create a new Azure web app for your service. After the publish, your service should be up and running. And since the swagger api is enabled, you will find the trial api on "<a href="https://&lt;yourservicename&gt;.azurewebsites.net">https://&lt;yourservicename&gt;.azurewebsites.net</a>"

Then you can go and compile the test client. Enter the name of your web app in program.cs. When you run it, it will connect to the service, create a device named "1234567" and send a few messages to the IoT hub. If you have device explorer connected, you can receive those messages and send a few back.

<strong>And now you should probably change that default API key ("1234") and republish.</strong>

Hope this helps,

H.]]></content:encoded>
    </item>
    <item>
      <title>My azure scripts on github</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/my-azure-scripts-on-github</link>
      <pubDate>Wed, 10 Dec 2014 06:58:24 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/2014/12/10/my-azure-scripts-on-github/</guid>
      <description><![CDATA[&#160;  Hi!  I’ve decided to put my azure scripts on Github, that keeps them in one place and I can...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>Hi!</p>  <p>I’ve decided to put my azure scripts on Github, that keeps them in one place and I can update whenever I find bugs.</p>  <p><a title="https://github.com/holgerkenn/azurescripts" href="https://github.com/holgerkenn/azurescripts">https://github.com/holgerkenn/azurescripts</a>&#160;</p>  <p>I have more scripts in the queue, but I first need to remove credentials, hostnames etc. before I put them on github.</p>  <p>Hope it helps,</p>  <p>H.</p>]]></content:encoded>
    </item>
    <item>
      <title>Linux and Azure Files: you might need some help here…</title>
      <link>https://docs.microsoft.com/archive/blogs/holgerkenn/linux-and-azure-files-you-might-need-some-help-here</link>
      <pubDate>Wed, 17 Sep 2014 08:48:57 GMT</pubDate>
      <dc:creator><![CDATA[Holger Kenn]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/holgerkenn/2014/09/17/linux-and-azure-files-you-might-need-some-help-here/</guid>
      <description><![CDATA[&#160;  Hi!  tl;dr: To mount Azure Files from linux, you need cifs support in the kernel, the right...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>Hi!</p>  <p>tl;dr: To mount Azure Files from linux, you need cifs support in the kernel, the right mount helper and versions recent enough to supports the SMB2 protocol version.</p>  <p>I just got a ping from a customer who had trouble mounting an Azure Files filesystem from Linux. According to the Azure team blog, this should work: <a title="http://blogs.msdn.com/b/windowsazurestorage/archive/2014/05/12/introducing-microsoft-azure-file-service.aspx" href="http://blogs.msdn.com/b/windowsazurestorage/archive/2014/05/12/introducing-microsoft-azure-file-service.aspx">http://blogs.msdn.com/b/windowsazurestorage/archive/2014/05/12/introducing-microsoft-azure-file-service.aspx</a>&#160;</p>  <p>So I tried it myself on a Ubuntu 14.04 LTS and found the following:</p>  <p>If I used smbclient, everything worked:</p>  <p>kenn@cubefileclient:~$ smbclient -d 3 //cubefiles.file.core.windows.net/cubefiletest &lt;storage key goes here&gt; -U cubefiles -m SMB2    <br />[lots of debug output deleted here]     <br />Connecting to 168.61.61.18 at port 445     <br />Doing spnego session setup (blob length=0)     <br />server didn't supply a full spnego negprot     <br />Got challenge flags:     <br />Got NTLMSSP neg_flags=0x628a8015     <br />NTLMSSP: Set final flags:     <br />Got NTLMSSP neg_flags=0x60088215     <br />NTLMSSP Sign/Seal - Initialising with flags:     <br />Got NTLMSSP neg_flags=0x60088215     <br />Domain=[X] OS=[] Server=[]     <br />smb: \&gt; dir</p>  <p>&#160; .&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; D&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0&#160; Mon Sep&#160; 8 14:49:55 2014    <br />&#160; ..&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; D&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0&#160; Mon Sep&#160; 8 14:49:55 2014     <br />&#160; testdir&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; D&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0&#160; Mon Sep&#160; 8 14:47:08 2014     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 83886080 blocks of size 65536. 83886080 blocks available     <br />Total bytes listed: 0     <br />smb: \&gt; quit</p>  <p>Don’t be alarmed by all those scary looking messages, I’m running smbclient with –d 3, so there are a lot of debug messages.</p>  <p>Now I tried to mount the filesystem:</p>  <p>kenn@cubefileclient:~$ sudo bash    <br />root@cubefileclient:~# mount -t cifs <a href="file:///\\\cubefiles.file.core.windows.net\cubefiletest">\\\\cubefiles.file.core.windows.net\\cubefiletest</a> /mountpoint -o vers=2.1,username=cubefiles,password=&lt;storage key goes here&gt;,dir_mode=0777,file_mode=0777     <br />mount: wrong fs type, bad option, bad superblock on <a href="file://\\cubefiles.file.core.windows.net\cubefiletest">\\cubefiles.file.core.windows.net\cubefiletest</a>,     <br />&#160;&#160;&#160;&#160;&#160;&#160; missing codepage or helper program, or other error     <br />&#160;&#160;&#160;&#160;&#160;&#160; (for several filesystems (e.g. nfs, cifs) you might     <br />&#160;&#160;&#160;&#160;&#160;&#160; need a /sbin/mount.&lt;type&gt; helper program)     <br />&#160;&#160;&#160;&#160;&#160;&#160; In some cases useful info is found in syslog – try     <br />&#160;&#160;&#160;&#160;&#160;&#160; dmesg | tail&#160; or so</p>  <p>OK, this did not work.</p>  <p>So let’s check if the cifs filesystem is actually in the kernel.</p>  <p>root@cubefileclient:~# grep cifs /proc/filesystems    <br />nodev&#160;&#160; cifs</p>  <p>Yes, looks good.</p>  <p>So is there a mount helper for cifs?</p>  <p>root@cubefileclient:~# ls -la /sbin/mount.cifs    <br />ls: cannot access /sbin/mount.cifs: No such file or directory</p>  <p>That’s it! we’re missing the mount helper!</p>  <p>root@cubefileclient:~# apt-get install cifs-utils</p>  <p>root@cubefileclient:~# mount -t cifs <a href="file:///\\\cubefiles.file.core.windows.net\cubefiletest">\\\\cubefiles.file.core.windows.net\\cubefiletest</a> /mountpoint -o vers=2.1,username=cubefiles,password=&lt;storage key goes here&gt;,dir_mode=0777,file_mode=0777</p>  <p>root@cubefileclient:~# mount    <br />[…]     <br /><a href="file:///\\\cubefiles.file.core.windows.net\cubefiletest">\\\\cubefiles.file.core.windows.net\\cubefiletest</a> on /mountpoint type cifs (rw)</p>  <p>root@cubefileclient:~# ls /mountpoint/    <br />testdir</p>  <p>So this is great, and I thought this was the bug our customer was hitting. But I was wrong: Even with installing the mount helper nothing worked. Even the smbclient did not work for him.</p>  <p>So I recreated his setup (based on Suse Enterprise 11) and I saw the following:</p>  <p>cubefileclient2:~ # smbclient -d 3 //cubefiles.file.core.windows.net/cubefiletest &lt;storage key goes here&gt; -U cubefiles -m SMB2    <br />[lots of debug output deleted here…]     <br />protocol negotiation failed: NT_STATUS_PIPE_BROKEN</p>  <p>And also the mount failed.</p>  <p>So I decided to look at what’s going on on the wire. I opened up a second ssh window to the VM and ran tcpdump on the second terminal while attempting to connect to Azure Files in the first. ( tcpdump –s 65535 –w tcpdump.pcap port 445&#160; to be precise)</p>  <p>Since the output of tcpdump wasn’t too enlightening, I decided to load the output using <a href="http://www.microsoft.com/en-us/download/details.aspx?id=4865" target="_blank">Microsoft Network Monitor</a> and look at the packets there. (To load the capture files from tcpdump, make sure they have the extension .pcap) And then it was quite obvious: </p>  <p>In Ubuntu 14.04 LTS:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/62/metablogapi/6116.image_66132FE6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-63-62-metablogapi/6116.image_5F00_66132FE6.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/62/metablogapi/7181.image_thumb_4B7C26B8.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-63-62-metablogapi/7181.image_5F00_thumb_5F00_4B7C26B8.png" width="360" height="281" /></a></p>  <p>In Suse Enterprise 11:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/62/metablogapi/7215.image_1D780983.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-63-62-metablogapi/7215.image_5F00_1D780983.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/62/metablogapi/2364.image_thumb_5B07F7FD.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-63-62-metablogapi/2364.image_5F00_thumb_5F00_5B07F7FD.png" width="361" height="243" /></a></p>  <p>The SMB2 protocol was missing. So I started looking at the version numbers of smbclient, the cifs mount helper and the kernel.</p>  <p>Suse: </p>  <p>cubefileclient2:~ # smbclient -V    <br />Version 3.6.3-0.54.2-3282-SUSE-CODE11-x86_64     <br />cubefileclient2:~ # uname -a     <br />Linux cubefileclient2 3.0.101-0.35-default #1 SMP Wed Jul 9 11:43:04 UTC 2014 (c36987d) x86_64 x86_64 x86_64 GNU/Linux     <br />cubefileclient2:~ # mount.cifs -V     <br />mount.cifs version: 5.1 </p>  <p>Ubuntu:    <br />root@cubefileclient:~# smbclient -V     <br />Version 4.1.6-Ubuntu     <br />root@cubefileclient:~# uname -a     <br />Linux cubefileclient 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux     <br />root@cubefileclient:~# mount.cifs -V     <br />mount.cifs version: 6.0 </p>  <p>So here’s the solution: The Suse Enterprise 11 images contain a cifs implementation both in the kernel and in smbclient that hasn’t the SMB2 protocol implemented yet. And Azure files requires SMB2 otherwise the protocol negotiation will fail.</p>  <p>One closing remark: Please check the date when this was posted, software versions change all the time and what is described here may not be accurate anymore when you read this. I’m not posting this to point to any specific bugs or to promote one distribution over the other. It’s just a fact of life that one cannot support everything with every single version of an OS or service, this post is intended to give you ideas what to look for and give you some tools to debug low-level system behavior. And of course one could have checked the version numbers first or looked for protocol version negotiation mismatches in the debug output. But when I have no clue what to look for, I found it sometimes helpful to start with the lowest level and work my way up until I find something.&#160; </p>  <p>Hope this helps,    <br />H.</p>]]></content:encoded>
    </item>
  </channel>
</rss>