Build Microsoft Azure SDK For OpenWrt System


      Cloud for organizing and analyzing  big data is a trend, Microsoft introduces Azure Cloud for IoT purpose. it has been announced cross-platform (even microchip) and easy to be ported.
      The Azure SDK is for this issue : if this SDK has been ported to the endpoint of IoT, the device could talk to Azure Cloud directly.
      But from my perspective, the called endpoints in Microsoft term are local-server/router, which be able to sort out data from the meters. The structure be :

In most case, the routers are embedded system based, those are high performance (compared to the microchip in the meters side), which are able to deliver the local reports to the persons on site.

Below steps is to explain how to port Azure to OpenWRT, which is very common in the IP routers.

零. Create a Azure acount:

  In the Azure website, https://www.azureiotsuite.com/, you should create a Microsoft account on Azure purpose. And it is necessary to input your credit number to pass the register. While the account has been created,do not forget to your e-mail box for certificating.
  Once your registering has been done, create a solution as remote monitor:




While launch the solution, add a device in that, that should be custom device(physics hardware device) :


Then, you could input the device id or it be generated automatically. In here, I request it generating the id in automation.

 The screen would show the information which should be recorded for later usage:

 The id, hostname and key should be input into sdk client code.

The last action in this step is to enable the device just be created:

 
(In the screen, you could seek out the column of device properties, where is the hostname, id and key written.)


一.  Build the Azure sdk in x86 Linux natively:
   You could refer to this  Azure website.

  Check the tools have been installed :

sudo apt-get install -y git cmake build-essential curl libcurl4-openssl-dev libssl-dev uuid-dev


Git clone the azure clone code from repository:

git clone --recursive https://github.com/Azure/azure-iot-sdk-c.git


Go into the azure sdk folder, create a folder for contain the built binaries and call cmake to configure the setting:
 

cd azure-iot-sdk-c
mkdir x86_64
cd x86_64
cmake ..
cmake --build . -- -j4 


(The last line could be simply replaced as "make -j4" )

And to the folder azure-iot-sdk-c/x86_64/serializer/samples/simplesample_mqtt, to run the binary simplesample_mqtt, which would generate fake datum and send it to the cloud:
 

gaiger@i5-3210M:~/azure-iot-sdk-c/x86_64/serializer/samples/simplesample_mqtt$ ./simplesample_mqtt 
Info: IoT Hub SDK for C, version 1.1.18
Error: Time:Fri Jul 14 00:18:32 2017 File:/home/gaiger/azure-iot-sdk-c/iothub_client/src/iothub_client_ll.c Func:IoTHubClient_LL_CreateFromConnectionString Line:547 Tokenizer error
Error: Time:Fri Jul 14 00:18:32 2017 File:/home/gaiger/azure-iot-sdk-c/iothub_client/src/iothub_client_ll.c Func:IoTHubClient_LL_CreateFromConnectionString Line:662 iotHubName is not found
Failed on IoTHubClient_LL_Create



The problem is very obvious that the device id, key and hostname should be written in the code.

Edit the file azure-iot-sdk-c/serializer/samples/simplesample_mqtt/simplesample_mqtt.c (NOT under the x86_64 folder),  modify the code about line 31:
 

/*String containing Hostname, Device Id & Device Key in the format:             */
/*  "HostName=;DeviceId=;SharedAccessKey="    */
//static const char* connectionString = "[device connection string]";
static const char* connectionString = \
                                "HostName=test-0-remote-monitor23fea.azure-devices.net;" \
                                "DeviceId=CoolingSampleDevice_2656;" \
                                "SharedAccessKey=3OuqHv7YyejvxVdsYcV2OIZSof5scZRIBnKVq61Sy6s=";


There should be no space inside the string, or the sending action would not be successful.

Rebuild (you could type make in folder azure-iot-sdk-c/x86_64/serializer/samples/simplesample_mqtt) and run again, the command line reveals :
 

gaiger@i5-3210M:~/azure-iot-sdk-c/x86_64/serializer/samples/simplesample_mqtt$ ./simplesample_mqtt 
Info: IoT Hub SDK for C, version 1.1.18
IoTHubClient accepted the message for delivery
Message Id: 0 Received.
Result Call Back Called! Result is: IOTHUB_CLIENT_CONFIRMATION_OK 


The data has been sent successfully.

To the cloud site, the result has been recorded:
(DO NOT forget to set "Device to View" in upright corner of Azure website as the same as the set device id !!)



If you feel awful why your record has ONE datum only but I have three, do not worry that,for I have run the binary 3 times.

Now, for easy debugging, modify the file azure-iot-sdk-c/serializer/samples/simplesample_mqtt/simplesample_mqtt.c to keep generate data per two seconds, about line 223:
 

                        /* wait for commands */
                        while (1)
                        {
                            IoTHubClient_LL_DoWork(iotHubClientHandle);
#if(0)                            
                            ThreadAPI_Sleep(100);
#else
                            ThreadAPI_Sleep(2*1000);
                            //myWeather->DeviceId = "myFirstDevice";
                            myWeather->WindSpeed = avgWindSpeed + (rand() % 4 + 2);
                            myWeather->Temperature = minTemperature + (rand() % 10);
                            myWeather->Humidity = minHumidity + (rand() % 20);
                            printf("WindSpeed = %d, Temperature = %3.1f, Humidity = %3.1f\r\n", 
                                myWeather->WindSpeed, myWeather->Temperature, myWeather->Humidity);
                            {
                                unsigned char* destination;
                                size_t destinationSize;
                                if (SERIALIZE(&destination, &destinationSize, 
                                        myWeather->DeviceId, myWeather->WindSpeed, 
                                        myWeather->Temperature, myWeather->Humidity) != CODEFIRST_OK)
                                {
                                    (void)printf("Failed to serialize\r\n");
                                }
                                else
                                {
                                    sendMessage(iotHubClientHandle, destination, destinationSize, myWeather);
                                    free(destination);
                                }
                            }
#endif
                        }



Rebuild and run again, you will find the data  from client to cloud ceaselessly:

gaiger@i5-3210M:~/azure-iot-sdk-c/x86_64/serializer/samples/simplesample_mqtt$ ./simplesample_mqtt 
Info: IoT Hub SDK for C, version 1.1.18
IoTHubClient accepted the message for delivery
WindSpeed = 12, Temperature = 22.0, Humidity = 72.0
IoTHubClient accepted the message for delivery
WindSpeed = 14, Temperature = 26.0, Humidity = 71.0
IoTHubClient accepted the message for delivery
WindSpeed = 13, Temperature = 29.0, Humidity = 77.0
IoTHubClient accepted the message for delivery
WindSpeed = 13, Temperature = 26.0, Humidity = 78.0
IoTHubClient accepted the message for delivery
WindSpeed = 13, Temperature = 20.0, Humidity = 74.0
IoTHubClient accepted the message for delivery
WindSpeed = 13, Temperature = 25.0, Humidity = 61.0
IoTHubClient accepted the message for delivery
WindSpeed = 13, Temperature = 21.0, Humidity = 73.0
IoTHubClient accepted the message for delivery
WindSpeed = 15, Temperature = 22.0, Humidity = 61.0
IoTHubClient accepted the message for delivery
Message Id: 0 Received.
:

 


To here, the x86 based client has been done.

二. Build OpenWrt system for preparing necessary toolchain and libraries.

I adopted OpenWRT-CC. To grab the code, use git clone in terminal :
 

sudo apt-get install subversion build-essential git-core libncurses5-dev zlib1g-dev gawk flex quilt libssl-dev xsltproc libxml-parser-perl mercurial bzr ecj cvs unzip git wget
git clone https://github.com/domino-team/openwrt-cc.git


The first line is for download the depended libraries, the second is to download the code.

Go into the openwrt-cc folder, type below command and wait a while (for downloading the libraries for menu),  you could configure the building:

.config - OpenWrt Configuration
 ──────────────────────────────────────────────────────────────────────────────
  ┌───────────────────────── OpenWrt Configuration ─────────────────────────┐
  │  Arrow keys navigate the menu.   selects submenus ---> (or empty │  
  │  submenus ----).  Highlighted letters are hotkeys.  Pressing         │  
  │  includes,  excludes,  modularizes features.  Press  to │  
  │  exit,  for Help,  for Search.  Legend: [*] built-in  [ ]         │  
  │ ┌─────────────────────────────────────────────────────────────────────┐ │  
  │ │        Target System (Atheros AR7xxx/AR9xxx)  --->                  │ │  
  │ │        Subtarget (Generic)  --->                                    │ │  
  │ │        Target Profile (TP-LINK TL-WR720N)  --->                     │ │  
  │ │        Target Images  --->                                          │ │  
  │ │        Global build settings  --->                                  │ │  
  │ │        Gl.iNet package choice shortcut  --->                        │ │  
  │ │    [ ] Advanced configuration options (for developers)  ----        │ │  
  │ │    [ ] Build the OpenWrt Image Builder                              │ │  
  │ │    [ ] Build the OpenWrt SDK                                        │ │  
  │ │    [*] Package the OpenWrt-based Toolchain                          │ │  
  │ └────┴(+)─────────────────────────────────────────────────────────────┘ │  
  ├─────────────────────────────────────────────────────────────────────────┤  
  │