Now Galileo is capable of accessing azure storage services
after several tries and tweaks. As you know Windows developer Program for IoT
released the Casablanca C++ REST SDK for accessing cloud services from Galileo
but this is not sufficient to access azure services and we need to port or
develop another layer on top of it to access specific Azure services. I
searched and fortunately found a C++ library that can specifically made to
access Azure storage services and again that is using the Casablanca C++ REST
SDK. Wow!!!. But this happiness was not withstood for long time after building
it and running it simply on Galileo. Let’s get hands dirty!!!
Prerequisites
- Supported for both Intel Galileo Gen1 and Gen2.
- Latest OS update released on 21-Nov-2014 (common .wim for Gen1 and Gen2) for lightning (improved performance on I2C, SPI, and UART etc..)
- Visual studio 2013 with Windows IoT SDK (Visit: windowsondevices.com for more details) and Microsoft IoT C++ SDK and its dependent NuGet Package is required.
- NuGet package for C++ REST SDK (Casablanca) Version ≥ 2.0.1 (tested with version 2.0.1 and 2.2.0)
- Source code for C++ REST SDK. Go through the instructions given in the below link.
- NuGet package for Microsoft Azure Storage Client Library for C++ 0.3.0-preview
- Source code for Azure Storage Client Library for C++ 0.3.0-preview from Github.
- Sample source code to access the Azure storage client library. I used the source code for accessing table for this example but it should work for all storage services.
Building the Casablanca C++ REST SDK
·
Refer the topic “Build Casablanca” and “Place
the lib on the Galileo” on this link http://ms-iot.github.io/content/Casablanca.htm
Building the Azure Storage Client
library for C++
- Go to Azure Storage Client Library for C++ 0.3.0-preview link and download the source code by clone or Download zip option. Unzip it and you can find the azure-storage-cpp-0.3.0-preview.
- Open the Micosoft.WindowsAzure.Storage.v.120.sln file.
- Go to Project » Properties » Configuration Properties » C/C++ » Code Generation
- Set Enable Enhanced Instruction Set = No Enhanced Instructions (/arch:IA32) for both Debug and Release
- Install the C++ REST SDK Nuget as shown below through the package manager console.
- Install-Package cpprestsdk –version 2.2.0
- Build the solution.
- Navigate to \\mygalileo\c$\test in file explorer (create the “test” folder if necessary).
- Copy the wastorage.dll file (generated during the build step and placed at \ azure-storage-cpp-0.3.0-preview \ Micosoft.WindowsAzure.Storage \v120\Win32\Debug), into the “test” folder from the previous step.
Building the Galileo Wiring
Application
- Create a “Galileo Wiring App” solution, let’s named as GalileoAzureStorage. You can download it from the below codeplex link. https://azurestorageclientgalileo.codeplex.com
- Add the source code for accessing the table shown in the prerequisites to the setup() function of Main.cpp. Install the C++ REST SDK and Azure Storage client library NuGet packages as shown on the prerequisites in addition to the basic Microsoft IoT C++ SDK and its dependencies.
- Install-Package cpprestsdk –version 2.2.0
- Install-Package wastorage -Version 0.3.0-preview –Pre
- Build the application, now your GalileoAzureStorage.exe is ready.
·
Copy both the cpprest120d_2_2.dll and
wastorage.dll to Galileo as mentioned in previous topics.
·
Run the program through remote windows debugger
and now the problem starts. The program doesn’t work as expected and you can
see the following error message in the output window.
Fig: Error Entry not found |
The error shows that the APIs linked during
the build is not found in the runtime. Which means the DLL contains the
corresponding API is missing or couldn’t able to forward to the corresponding
DLL in the OS.
Troubleshooting
I have
reported this issue to Microsoft through connect last month and IoT team has
proposed some suggestion to resolve the issues and now it is published on the
windowsondevices.com as forwarder
and Stubs. Thanks for Microsoft support to achieve this.
Linking Azure Storage client with
Mincore.lib
- Build the Azure storage client library by linking with mincore.lib instead of using the default library.
- Go to Micosoft.WindowsAzure.Storage.v.120 Project >> Properties >> Linker >> Input.
- Remove the default entries (legacy libraries) in additional Dependencies and add mincore.lib and xmllite.lib (This is required for this project.)
Fig : Default Libraries |
- Make sure that you have de selected the inherit option as shown in the below image.
Fig ) Adding Mincore.lib |
- Add the list of libraries you have to exclude, in the “ Ignore Specific Default Libraries”
Fig) excluding the default libs. |
- Build and Copy the wastorage.dll to \\mygalileo\C$\test folder. and run the application but still you will get the same “Entry Not Found” error.
Find the Missing APIs and its
dependencies
- Refer the Diagnosing a failing application topic on the Forwarder and stubs link.
- Replace the Node.exe with GalileoAzureStorage.exe in the command given in the above link.
- Run the application again from “Remote Windows Debugger”.
- Now the detailed APIs and its corresponding DLLs are listed in your output window while loading the application and finally found the Missing APIs Name.
- Following two APIs Entry Points are missing.
o UnregisterClassW
o
MessageBoxW
·
Windows on Galileo is derived from Windows Phone
8.1. This mobile edition of Windows uses the Windows 8.1 API Set. You can find the list of APIs
supported in mincore library in this link.
Forwarder and stubs
If the missing APIs are listed in the Windows 8.1 API Set,
you can choose forwarder option. Refer the “Forwarder” topic in the Forwarder and stubs
link. Our case, the above listed APIs are not listed in the Windows 8.1 API
Set. These two APIs are belongs to User32.dll but unfortunately the Galileo Windows
version of User32.dll doesn’t contain the two APIs. So you have to develop a
stub User32.dll for the APIs and link it while loading the application.
Building User32.dll
Fortunately you already have the User32 stub project created
by Microsoft IoT team and now you can download the project, add the stub and
build your own user32.dll as explained in the “Forwarder and Stub repository”
topic in the Forwarder
and stubs link. You can also contribute back to the Github. I have summited my pull request after this
changes.
·
Add the missing API names in the sources.def
file in the User32 project as shown below.
Fig: sources.def of User32 Project |
- Add the stubs for these API in stubs.cpp.
Fig: Missing APIs stubs in Stubs.cpp |
- Build it and copy the User32.dll to \\mygalileo\c$\test
- Make sure the cpprest120d_2_2.dll and wastorage.dll are in the same location as mentioned in the previous step.
- Run the GalileoAzureStorage.exe from “remote windows debugger”. Now the program loaded successfully without loading issues but unfortunately we have another issue happened during application execution. Come on! Let’s not give up.
Exception due to server
“Authentication Failed”
After captured the azure storage exception it shows that the
server failed to authenticate for the request due to incorrect authentication
header as shown below.
Fig: Authentication Failed |
But the strange behaviour is, the same application (binaries
along with the DLLs) run without any issue on windows 8.1 PC. Good news is, At least
I have an option to trace the authentication header difference between PC and
Galileo.
Of course, this approach worked well. I have captured the
authentication header of PC and Galileo as shown below. If you compare it you
can find the difference in the x-ms-date member of the Authentication headers
between PC and Galileo.
Fig: Correct date and time format in PC for x-ms-date |
Fig: Wrong date and time format in Galileo for x-ms-date |
If you trace the code, The x-ms-date member is filled by the
function called shared_key_authentication_handler::sign_request()
of “azure-storage-cpp-0.3.0-preview\azure-storage-cpp-0.3.0-preview\Microsoft.WindowsAzure.Storage\src
authentication.cpp” file.
Again don’t give up. Let’s trace further to find the root
cause of this issue. if you see the source code of the above function there is
some other utility function is called inside to get the date and time to fill
the x-ms-date member of the authentication header.
Fig: Getting time from Date time utility |
Workaround in C++ REST SDK
If you trace it further, This “datetime” utility function is
a part of the C++ REST SDK. You can find the function datetime::to_string(date_format format) in casablanca\casablanca\Release\src\utilities\
asyncrt_utils.cpp. This function using the GetDateFormatEx()
WIN32 API to retrieve the RFC_1123 date
format. Unfortunately this API not returns the required time format in Galileo
but in Windows 8.1 PC is it working as expected. So here I made a workaround
for this issue. Comment the existing code related to GetDateFormatEx() and
replace it with our own code as shown below.
Fig) workaround to get the RFC_1123 date format |
·
- Rebuild the C++ REST SDK and copy the cpprest120d_2_2.dll to \\mygalileo\c$\test\ folder.
- Run again the GalileoAzureStorage.exe from “remote windows debugger”. SUCCESS !!!!.
- You can’t see the table entries in Azure portal, instead there are some third party tools are available to play with the tables. I used Azure storage explorer 6 downloaded from codeplex.
- GalileoAzureStorage.exe will perform create table , add data, retrieve data and delete table.
Conclusion
GalileoAzureStorage project available on codeplex.Now pushing
sensor data to cloud is a cakewalk from Windows on Galieo. Enjoy real IoT-ing on Galileo.
Vinoth,
ReplyDeleteI finally found some time to try this out. It worked exactly as you described. Your explanations of the problems and their solutions saved me a lot of time, and your detective work on the Authentication date problem was truly impressive. Thanks!
I've just started logging some sensor data to Azure based on the sample code from your "sensors to server" article. So far, so good.
If you are still using your Galileo with Azure, what has your experience been with stability: does the Galileo keep posting to Azure without any downtime or errors?
Thanks,
Dan.
Hello Dan,
ReplyDeleteThanks for reading this article. I testes the Azure storage services for few hours from Galileo.I didn't noticed any issue. But i tested the Azure Service Bus (event hubs) for 24 hours from Galileo. i didn't noticed any issue.
Regards,
Vinoth