Keil Logo

Azure IOT with Keil MDK

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Author
David Nicholls
Posted
14-May-2019 11:10 GMT
Toolset
None
New! Azure IOT with Keil MDK

I'm trying to implement an Azure IOT hub connection with MQTT using a custom WiFi driver. Has anyone else had any experience with this as I am having some problems?

My problem seems to be with the Azure SDK part of it, I know the WiFI driver is functioning correctly as I've already been using it with the Paho MQTT packet and the Eclipse broker.

I have my iot socket functions currently stubbed off and the first one that seems to get called is iotSocketGetHostByName() with the first argument being a pointer to the broker URL, but the URL is empty.

I believe I have setup the connection string correctly and I can step through the code to see that the url of the azure iot hub is being extracted correctly and is being stored. However it doesn't get passed to the iotSocketGetHostByName() function as it's not stored in the dns->hostname variable.

Any thoughts please.

Author
Robert Rostohar
Posted
15-May-2019 09:17 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

It seems that you did not configure properly the connection string to Azure servers.

You can take a look at the Azure IoT pack (MDK-Packs::Azure_IoT).

Getting started document:
https://github.com/MDK-Packs/Azure_IoT/blob/master/contributions/add/doc/Azure_IoT_MDK.md

Make sure that you have created an IoT hub and registered your device (see section "In the Microsoft Azure portal").

Code that connects to the cloud typically uses the Connection String (primary key obtained from Azure portal) that includes also the HostName.

Take a look at the Telemetry sample described in the above getting started document (see section Add Template code - Telemetry sample code).

Author
David Nicholls
Posted
15-May-2019 10:04 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

Hi Robert,

I should have said that I did follow that procedure. The main difference is that I have left out the network components as I'm using a WiFi device.

I am using the telemetry sample and I believe the IOT Hub is setup correctly. The connection string I am using is from the "Connection String (primary key)" field. This is it, with some parts replaced with *.

HostName=H**V****.azure-devices.net;DeviceId=********;SharedAccessKey=***emtkN0K/tj8pRqe5w5KgE/UNUzX+/IaEPf6I9R6s=

Author
Robert Rostohar
Posted
15-May-2019 10:06 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

It might be also that you don't have enough heap.

You should debug the application to see where it breaks.

DNS resolver is started first in the function dns_async_create (module: c-utility\pal\mdk\dns_async.c).
The function receives the "hostname" string which is copied to allocated memory for DNS instance.
Check if "hostname" is a valid string and if it gets copied to DNS->hostname.

if (hostname == NULL)
{
  ...
}
else
{
  result = malloc(sizeof(DNS_ASYNC_INSTANCE));
  if (result == NULL)
  {
  }
  else
  {
    ...
    mallocAndStrcpy_s(&result->hostname, hostname);
    ...
  }

It could be that the allocation fails in the function or hostname was already NULL due to some issue before that.

Depending on that you should investigate further.

Call chain:
iothub_client\src\iothubtransport_mqtt_common.c\IoTHubTransport_MQTT_Common_DoWork
>InitializeConnection(PMQTTTRANSPORT_HANDLE_DATA transport_data)
transport_data->hostAddress should contain the string pointer to hostname
>> umqtt\src\mqtt_client.c\mqtt_client_connect()
>>> c-utility\src\xio.c\xio_open
>>>> c-utility\pal\mdk\tlsio_mbedtls.c\tlsio_mbedtls_open
>>>>> c-utility\pal\mdk\dns_async.c\dns_async_create

Author
David Nicholls
Posted
15-May-2019 13:40 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

I can see that the hostname isn't availble in transport_data->hostAddress.

Going back earlier in the chain, the function IoTHubClient_LL_CreateFromConnectionString() appears to be finding the host name correctly and placing it in config which is passed to initialize_iothub_client() with no error. From there it doesn't get into transport_data->hostAddress.

There is so much pointer work that it is difficult to trace where it is meant to go!

However I have found that in function InitializeTransportHandleData() at the line:

state->hostAddress = STRING_construct_sprintf("%s.%s", upperConfig->iotHubName, upperConfig->iotHubSuffix);

The hostAddress isn't populated. This seems to be because in STRING_construct_sprintf(), STRINGS_C_SPRINTF_BUFFER_SIZE isn't defined.

Should it be?

As a test, I have defined it in the target C/C++ preprocessor symbols and now the host address is appearing in my SocketGetHostByName(). So the define seems to work but is this correct and what other side affects may this cause?

Author
Robert Rostohar
Posted
15-May-2019 14:03 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

As you have also realized the Azure IoT SDK is quite complex and not so easy to understand or debug.

The function STRING_construct_sprintf will allocate needed memory from heap when STRINGS_C_SPRINTF_BUFFER_SIZE is not defined. So it does not need to be defined explicitly.

I suspect that allocating memory fails in your configuration. You should debug the mentioned function to confirm. Have you tried to increase Heap?

Alternative would be to define that buffer size however I’m not sure what is a good value because this function is used in many different places and having the buffer too small might lead to other failures.

Author
David Nicholls
Posted
15-May-2019 16:23 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

The heap is currently set to 64kB.

If the STRINGS_C_SPRINTF_BUFFER_SIZE is not defined then the arguments for the maxBufSize is set to 0. The function vnsprint then should return the length that the string would be if the buffer was long enough, instead it is returning 0 so then the next part of the function is jumped over and so we don't even get to allocation of memory.

In fact this function is called several times and vnsprintf always returns with a length of 0.

I have done a test with my own function defined as:

int32_t myConstruct_sprintf(const char* format, ...)
{ size_t maxBufSize = 0; char* buf = NULL; int32_t len; va_list arg_list;

va_start(arg_list, format);

len = vsnprintf(buf, maxBufSize, format, arg_list);

va_end(arg_list);

return len;
}

when I call it with:

int32_t length = myConstruct_sprintf("%s.%s", "abc", "xyz");

length is returned as 0, it should be 7.

Author
Andrew Neil
Posted
15-May-2019 17:17 GMT
Toolset
None
New! How to properly post source code.


http://www.keil.com/forum/tips.asp

Author
Robert Rostohar
Posted
16-May-2019 06:38 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

This is strange. I get the expected 7 as return value when I try your test function.

Which compiler (and version) are you using?
What compiler options are you using (target, optimization, other special options, …)?

Author
David Nicholls
Posted
16-May-2019 08:06 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

I have 5.26.2.0.

I tried a clean new project and initially with the default setup I got 7. However when I turned on Use MicroLIB then it failed with 0 returned.

I probably don't need to use MicroLIB, I don't remember my reason for turning it on. But I think the function should still work with it?

Author
Robert Rostohar
Posted
16-May-2019 08:31 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

Microlib is an alternative to the default C library tailored for deeply embedded applications. It is highly optimized for small code size.

Microlib does not attempt to be an ISO C-compliant library.
http://www.keil.com/support/man/docs/armlib/armlib_chr1358938938181.htm

This might explain behavior of vsnprintf when using NULL pointer and 0 size.

It seems that you should not use Microlib with the Azure SDK.

Author
David Nicholls
Posted
16-May-2019 09:08 GMT
Toolset
None
New! RE: Azure IOT with Keil MDK

I know not to use it now.

Thanks for your help in tracing this issue.

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.