2
votes

I'm using a 32-bit microcontroller (program code written in C) with very limited flash space that is communicating with a cellular module. I have an Azure account setup with an IoT Hub and I would like to send some device-to-cloud messages to my IoT Hub. I have tested and confirmed both HTTP and HTTPS communication to other servers. However, I can't find anywhere that specifies what the required HTTP headers are for sending a device-to-cloud message. Can anyone provide a description of the required HTTP message format (the HTTP start line, required HTTP headers and the HTTP header values)?

I found the Azure SDK for C, but even with all the optimization options turned on it takes up too much codespace for my microcontroller. I've tried following the code in the SDK for how the HTTP message is built, but I seem to be missing some pieces. I only have two or three device-to-cloud messages that I am sending, so I assume that if I know what the headers are it won't take much code to generate the device-to-cloud messages.

The cellular module I have is handling the X.509 certificates for mutual TLS authentication. Assume that is working. For this question I'm only concerned with finding the required HTTP message formatting for a Azure IoT device-to-cloud message.

EDIT: Following a suggestion from a comment, I was eventually led to this page: https://docs.microsoft.com/en-us/rest/api/iothub/device/senddeviceevent

Using the suggested HTTP POST (with my device specifics replaced), I am now getting a 401 error (IotHubUnauthorizedAccess). I thought I understood how the authentication was supposed to work, but I guess I was wrong.

My IoT device has a symmetric key. I thought I was supposed to include a header formatted as:

Authorization:SharedAccessKey=<my_primary_key>

but that doesn't work. My HTTP body is simply:

{"deviceID":<my_IoT_Device_ID>}

Where am I supposed to include the symmetric key information, and what is its format?

1
We'd absolutely love to help you enable the SDK on your device. Can you help us by elaborating on the specific specs of your device and your requirements (only D2C?)? If you can file an issue here, that'd be great. We are collecting feedback regarding SDK footprint and want to optimize it further for constrained devices.Yi Zhong - MSFT
This document has guidance on how to use the MQTT protocol directly with IoTHub without using the Azure IoT device SDK: docs.microsoft.com/en-us/azure/iot-hub/… If you see anything missing or areas for improvement, please log an issue on the documentation page.Stefan Wick MSFT
You need to generate the SAS token (based on your device key), but it's not the device key itself. See github.com/Microsoft/vscode-azure-iot-toolkit/wiki/… and here for ways to do it: github.com/kvaes/…silent
Are the SAS tokens required for authentication? I followed the steps in the link above and, using Postman, I was able to successfully send a D2C message with the SAS token I generated on my Azure portal using the Azure CLI. I don't think my microcontroller is capable of calculating a SAS token.bevenson

1 Answers

1
votes

After some trial and error, we found out it's much easier than we thought. If you are using X.509 certificates for client authentication, you don't need to include anything in the HTTP message content to specify your authentication. The minimum required for an Azure device-to-cloud message using X.509 certificates for authentication is:

POST /devices/<id>/messages/events?api-version=2018-06-30 HTTP/1.1
Host:<fully-qualified-iothubname>.azure-devices.net
Content-Length:<number-of-bytes-in-the-JSON-body>

{"deviceID":"<id>",<your-JSON-formatted-custom-d2c-message-data>}

where <id> is the device ID as listed on the Azure IoT Hub and <fully-qualified-iothubname> is the IoT Hub name. I believe Azure supports chunked encoding if you want to do that instead of using the Content-Length header.