Skip to content

Latest commit

 

History

History
689 lines (447 loc) · 33.9 KB

README.md

File metadata and controls

689 lines (447 loc) · 33.9 KB

Azure IoT Samples

Table of Contents

Introduction

This document explains samples for the Azure Embedded C SDK IoT Hub Client and Device Provisioning Client.

Samples are designed to highlight the function calls required to connect with the Azure IoT Hub or the Azure IoT Hub Device Provisioning Service (DPS). These calls illustrate the happy path of the mqtt state machine. As a result, these samples are NOT designed to be used as production-level code. Production code needs to incorporate other elements, such as connection retries and more extensive error-handling, which these samples do not include. These samples also utilize OpenSSL, which is NOT recommended to use in production-level code on Windows or macOS.

The samples' instructions include specifics for both Windows and Linux based systems. For Windows, the command line examples are based on PowerShell. The Linux examples are tailored to Debian/Ubuntu environments. Samples are also designed to work on macOS systems, but the instructions do not yet include specific command line examples for this environment. While Windows and Linux devices are not likely to be considered constrained, these samples enable developers to test the Azure SDK for Embedded C libraries, debug, and step through the code, even without a real device. We understand not everyone will have a real device to test and that sometimes these devices won't have debugging capabilities.

WARNING: Samples are generic and should not be used in any production-level code.

More detailed step-by-step guides on how to run an IoT Hub Client sample from scratch can be found below:

To view scenario-focused examples using the API calls, please view the Azure IoT Client introductory examples. General coding patterns that are MQTT stack agnostic are also available to view.

Github Codespaces

You can use Github Codespaces to be up and running quickly! Here are the steps to follow (assuming you already have an IoT Hub set up).

  1. Select the "Open with Codespaces" prompt on Github and then "New codespace".

  1. Once the Codespace is open, all required build tools, extensions, and debugging tools will be setup for you.
  2. Hit Control-Shift-B on your keyboard to build the SDK and samples.
  3. Navigate to the cert/ directory and find the fingerprint for the certificate that was generated for you.
  4. In the Azure IoT Hub portal, add a device using Self-Signed Cert authentication. Paste the fingerprint in for Primary and Secondary. Add the device.
  5. Back in the Codespace, navigate to the "Run" tab on the left side (arrow with a bug).
  6. Select any of the samples and hit the green run button.
  7. Paste you Device ID and IoT Hub Hostname in the prompts that pop up. Hit enter and the sample should be running!
  8. Note you can use the device explorer to monitor/interact with the samples.

Prerequisites

To run the samples, ensure you have the following programs and tools installed on your system:

  • Have an Azure account created.

  • Have an Azure IoT Hub created.

  • Have the following build environment setup:

    Instructions:

    Linux:

    sudo apt-get update
    sudo apt-get install build-essential curl zip unzip tar pkg-config

    Windows (PowerShell):

  • Have Git installed.

  • Have Microsoft vcpkg package manager and Eclipse Paho MQTT C client installed. This installation may take an extended amount of time (~15-20 minutes).

    Instructions:

    NOTE: For the correct vcpkg commit, see vcpkg-commit.txt.

    Linux:

    git clone https://github.com/Microsoft/vcpkg.git
    cd vcpkg
    git checkout <vcpkg commit> # Checkout the vcpkg commit per vcpkg-commit.txt above.
    ./bootstrap-vcpkg.sh
    ./vcpkg install --triplet x64-linux curl cmocka paho-mqtt

    Windows (PowerShell):

    git clone https://github.com/Microsoft/vcpkg.git
    cd vcpkg
    git checkout <vcpkg commit> # Checkout the vcpkg commit per vcpkg-commit.txt above.
    .\bootstrap-vcpkg.bat
    .\vcpkg.exe install --triplet x64-windows-static curl[winssl] cmocka paho-mqtt # Update triplet per your system.

  • Have OpenSSL installed.

    Instructions:

    Linux:

    sudo apt-get install openssl libssl-dev

    Windows (PowerShell):

    • OpenSSL will be installed by vcpkg as a dependency for Eclipse Paho.

      WARNING: It is NOT recommended to use OpenSSL in production-level code on Windows or macOS.

      # NOT RECOMMENDED to use for production-level code.
      $env:PATH=$env:PATH + ';<FULL PATH to vcpkg>\installed\x64-windows-static\tools\openssl' # Update complete path as needed.

  • Have CMake installed. The minimum required is 3.10.

    Instructions:

    Linux:

    • Ubuntu 18.04 or 20.04:

      sudo apt-get install cmake
    • Ubuntu 16.04: Download the latest version of CMake.

      wget https://cmake.org/files/v3.18/cmake-3.18.3-Linux-x86_64.sh # Use latest version.
      sudo ./cmake-3.18.3-Linux-x86_64.sh --prefix=/usr
      • When prompted to include the default subdirectory, enter n so to install in /usr/local.

    Windows (PowerShell): Download the latest version of CMake.

    • Use the Windows installer.

  • Have the Azure SDK for Embedded C IoT repository cloned.

    NOTE: On Windows, due to the length of the repository filepaths, clone near the C:\ root.

    git clone https://github.com/Azure/azure-sdk-for-c.git
  • Executable: paho_iot_pnp_with_provisioning_sample

  • If running a DPS sample: paho_iot_provisioning_sample, paho_iot_pnp_with_provisioning_sample.

  • If running an IoT Plug and Play sample: paho_iot_pnp_sample, paho_iot_pnp_with_provisioning_sample, paho_iot_pnp_component_sample.

    • Have the most recent version of Azure IoT Explorer installed and connected to your Azure IoT Hub. More instructions on can be found here.

Getting Started

Create an Authenticated Device

Next you must create and connect an authenticated device. You can authenticate in one of two ways: via X.509 Self-Signed Certificate Authentication or Symmetric Key (SAS). You also must choose how you want to connect the device, either via Azure IoT Hub or via Azure IoT Hub Device Provisioning Service (DPS).

Create a Device Using X.509 Self-Signed Certificate Authentication

This approach must be used for the following samples: paho_iot_hub_c2d_sample, paho_iot_hub_methods_sample, paho_iot_hub_telemetry_sample, paho_iot_hub_twin_sample, paho_iot_pnp_sample, paho_iot_pnp_component_sample, paho_iot_pnp_with_provisioning_sample, paho_iot_provisioning_sample

As a convenience, we provide a series of commands below for you to create a temporary certificate in order to run the samples. These certificates expire after 30 days and are provided ONLY to help you easily understand CA Certificates. When productizing against CA Certificates, you will need to use your own security best practices for certificate creation and lifetime management.

WARNING: Certificates created by these commands MUST NOT be used in production-level code.

Linux Certificate Creation
  1. Enter the directory azure-sdk-for-c/sdk/samples/iot/.

  2. Run the following commands:

    openssl ecparam -out device_ec_key.pem -name prime256v1 -genkey
    openssl req -new -days 30 -nodes -x509 -key device_ec_key.pem -out device_ec_cert.pem -extensions client_auth -config x509_config.cfg -subj "/CN=paho-sample-device1"
    openssl x509 -noout -text -in device_ec_cert.pem
    
    rm -f device_cert_store.pem
    cat device_ec_cert.pem device_ec_key.pem > device_cert_store.pem
    
    openssl x509 -noout -fingerprint -in device_ec_cert.pem | sed 's/://g'| sed 's/\(SHA1 Fingerprint=\)//g' | tee fingerprint.txt
    
    export AZ_IOT_DEVICE_X509_CERT_PEM_FILE_PATH=$(pwd)/device_cert_store.pem
  3. The resulting thumbprint will be placed in fingerprint.txt and the generated pem file is named device_ec_cert.pem.

Windows Certificate Creation
  1. Enter the directory azure-sdk-for-c\sdk\samples\iot\.

  2. Run the following commands:

    openssl ecparam -out device_ec_key.pem -name prime256v1 -genkey
    openssl req -new -days 30 -nodes -x509 -key device_ec_key.pem -out device_ec_cert.pem -extensions client_auth -config x509_config.cfg -subj "/CN=paho-sample-device1"
    openssl x509 -noout -text -in device_ec_cert.pem
    
    Get-Content device_ec_cert.pem, device_ec_key.pem | Set-Content device_cert_store.pem
    
    openssl x509 -noout -fingerprint -in device_ec_cert.pem | % {$_.replace(":", "")} | % {$_.replace("SHA1 Fingerprint=", "")} | Tee-Object fingerprint.txt
    
    $env:AZ_IOT_DEVICE_X509_CERT_PEM_FILE_PATH=$(Resolve-Path device_cert_store.pem)
  3. The resulting thumbprint will be placed in fingerprint.txt and the generated pem file is named device_ec_cert.pem.

Create a device
  • To add a new device via Azure IoT Hub, see instructions here. However, DO NOT select X.509 CA Signed as the authentication type. Select X.509 Self-Signed. For the Thumbprint, use the recently generated fingerprint, which has been placed in the file fingerprint.txt.
  • To add a new individual device enrollment via Azure IoT Hub DPS, see instructions here. You will use the recently generated device_ec_cert.pem file. After creation, the Registration ID of your device should appear as paho-sample-device1 in the Individual Enrollments tab.

Create a Device Using Symmetric Key (SAS) Authentication

This approach must be used for the following samples: paho_iot_hub_sas_telemetry_sample, paho_iot_provisioning_sas_sample,

  • To add a new device via Azure IoT Hub, see instructions here.
  • To add a new individual device enrollment via Azure IoT Hub DPS, see instructions here. After creation, the Registration ID of your device will appear in the Individual Enrollments tab.

Set Environment Variables

Samples use environment variables for a variety of purposes, including filepaths and connection parameters. Please keep in mind, every time a new terminal is opened, the environment variables will have to be reset. Setting a variable will take the following form:

Linux:

export ENV_VARIABLE_NAME=VALUE

Windows (PowerShell):

$env:ENV_VARIABLE_NAME='VALUE'

All-Samples

Set the following environment variables for all samples:

  1. Set the vcpkg environment variables.

    Refer to these directions for more detail.

    Linux:

    export VCPKG_DEFAULT_TRIPLET=x64-linux
    export VCPKG_ROOT=<FULL PATH to vcpkg>

    Windows (PowerShell):

    $env:VCPKG_DEFAULT_TRIPLET='x64-windows-static' # Update triplet to match what was used during vcpkg install.
    $env:VCPKG_ROOT='<FULL PATH to vcpkg>'
  2. Set the trust pem filepath. Only when testing on Windows or OSX.

    Important: We recommend using a managed trusted store for production deployments. Paho/OpenSSL on Windows is meant for testing purposes only.

    Create a PEM certificate file based store by concatenating the following files:

    Make sure the files are in PEM format. If they are not, use openssl x509 -inform DER -outform PEM -in my_certificate.crt -out my_certificate.pem to convert them to PEM format. Concatenate all the files into CAStore.pem. Configure the AZ_IOT_DEVICE_X509_TRUST_PEM_FILE_PATH to point to this PEM file.

    Windows (PowerShell):

    $env:AZ_IOT_DEVICE_X509_TRUST_PEM_FILE_PATH='<FULL PATH TO>\CAStore.pem'

IoT Hub X.509 Certificate Samples

Set the following environment variables if running any of these samples: paho_iot_hub_c2d_sample, paho_iot_hub_methods_sample, paho_iot_hub_telemetry_sample, paho_iot_hub_twin_sample, paho_iot_pnp_sample, paho_iot_pnp_component_sample

Instructions to set environment variables for IoT Hub X.509 Certificate samples:

  1. Retrieve variable information:

    Access your Azure IoT Hub from either your Azure Portal or Azure IoT Explorer.

    • AZ_IOT_HUB_DEVICE_ID: From the IoT devices tab, select your device. Copy its Device Id.
    • AZ_IOT_HUB_HOSTNAME: From the Overview tab, copy your Azure IoT hub Hostname.
  2. Set the variables:

    Linux:

    export AZ_IOT_HUB_DEVICE_ID=<device-id>
    export AZ_IOT_HUB_HOSTNAME=<hostname>

    Windows (PowerShell):

    $env:AZ_IOT_HUB_DEVICE_ID='<device-id>'
    $env:AZ_IOT_HUB_HOSTNAME='<hostname>'

IoT Provisioning X.509 Certificate Sample

Set the following environment variables if running the sample: paho_iot_pnp_with_provisioning_sample, paho_iot_provisioning_sample

Instructions to set environment variables for DPS X.509 Certificate sample:

  1. Retrieve variable information:

    Access your Azure IoT Hub Device Provisioning Service from your Azure Portal.

    • AZ_IOT_PROVISIONING_REGISTRATION_ID: Set this to paho-sample-device1.
    • AZ_IOT_PROVISIONING_ID_SCOPE: From the Overview tab, copy the Id Scope.
  2. Set the variables:

    Linux:

    export AZ_IOT_PROVISIONING_REGISTRATION_ID=<registration-id>
    export AZ_IOT_PROVISIONING_ID_SCOPE=<id-scope>

    Windows (PowerShell):

    $env:AZ_IOT_PROVISIONING_REGISTRATION_ID='<registration-id>'
    $env:AZ_IOT_PROVISIONING_ID_SCOPE='<id-scope>'

IoT Hub Symetric Key (SAS) Sample

Set the following environment variables if running the sample: paho_iot_hub_sas_telemetry_sample

Instructions to set environment variables for IoT Hub Symmetric Key sample:

  1. Retrieve variable information:

    Access your Azure IoT Hub from either your Azure Portal or Azure IoT Explorer.

    • AZ_IOT_HUB_SAS_DEVICE_ID: From the IoT devices tab, select your device. Copy its Device Id.
    • AZ_IOT_HUB_SAS_KEY: From the same page, copy its Primary Key.
    • AZ_IOT_HUB_HOSTNAME: From the Overview tab, copy your Azure IoT hub Hostname.
  2. Set the variables:

    Linux:

    export AZ_IOT_HUB_SAS_DEVICE_ID=<sas-device-id>
    export AZ_IOT_HUB_SAS_KEY=<sas-key>
    export AZ_IOT_HUB_HOSTNAME=<hostname>

    Windows (PowerShell):

    $env:AZ_IOT_HUB_SAS_DEVICE_ID='<sas-device-id>'
    $env:AZ_IOT_HUB_SAS_KEY='<sas-key>'
    $env:AZ_IOT_HUB_HOSTNAME='<hostname>'

IoT Provisioning Symmetric Key (SAS) Sample

Set the following environment variables if running the sample: paho_iot_provisioning_sas_sample

Instructions to set environment variables for DPS Symmetric Key sample:

  1. Retrieve variable information:

    Access your Azure IoT Hub Device Provisioning Service from your Azure Portal.

    • AZ_IOT_PROVISIONING_SAS_REGISTRATION_ID: From the Manage enrollments tab, under Individual Enrollments, copy the Registration Id of your SAS device.
    • AZ_IOT_PROVISIONING_SAS_KEY: Under Individual Enrollments, select your SAS device. Copy its Primary Key.
    • AZ_IOT_PROVISIONING_ID_SCOPE: From the Overview tab, copy the Id Scope.
  2. Set the variables:

    Linux:

    export AZ_IOT_PROVISIONING_SAS_REGISTRATION_ID=<sas-registration-id>
    export AZ_IOT_PROVISIONING_SAS_KEY=<sas-key>
    export AZ_IOT_PROVISIONING_ID_SCOPE=<id-scope>

    Windows (PowerShell):

    $env:AZ_IOT_PROVISIONING_SAS_REGISTRATION_ID='<sas-registration-id>'
    $env:AZ_IOT_PROVISIONING_SAS_KEY='<sas-key>'
    $env:AZ_IOT_PROVISIONING_ID_SCOPE='<id-scope>'

Build and Run the Sample

  1. Build the Azure SDK for Embedded C directory structure.

    From the root of the SDK directory azure-sdk-for-c:

    mkdir build
    cd build
    cmake -DTRANSPORT_PAHO=ON ..
  2. Compile and run the sample.

    Linux:

    cmake --build .
    ./sdk/samples/iot/<sample executable here>

    Windows (PowerShell):

    .\az.sln
    • Navigate to the "Solution Explorer" panel and find the sample project you would like to run.
    • Right-click on the sample project, then click on "Set as Startup Project". (This makes it the default startup project.)
    • Build and run the project (F5 on most installations).

Sample Descriptions

This section provides an overview of the different samples available to run and what to expect from each.

IoT Hub C2D Sample

  • Executable: paho_iot_hub_c2d_sample

    This sample receives incoming cloud-to-device (C2D) messages sent from the Azure IoT Hub to the device. It will successfully receive up to 5 messages sent from the service. If a timeout occurs while waiting for a message, the sample will exit. X509 authentication is used.

    How to interact with the C2D sample:

    To send a C2D message: Select your device's "Message to Device" tab in the Azure Portal for your IoT Hub. Enter a message in the "Message Body" and select "Send Message".

IoT Hub Methods Sample

  • Executable: paho_iot_hub_methods_sample

    This sample receives incoming method commands invoked from the the Azure IoT Hub to the device. It will successfully receive up to 5 method commands sent from the service. If a timeout occurs while waiting for a message, the sample will exit. X509 authentication is used.

    How to interact with the Methods sample:

    A method named ping is supported for this sample.

    To invoke a method: Select your device's "Direct Method" tab in the Azure Portal for your IoT Hub. Enter a method name and select "Invoke Method". If successful, the sample will return a JSON payload of the following:

    {"response": "pong"}

    No other method commands are supported. If any other methods are attempted to be invoked, the log will report the method is not found.

IoT Hub Telemetry Sample

  • Executable: paho_iot_hub_telemetry_sample

    This sample sends five telemetry messages to the Azure IoT Hub. X509 authentication is used.

IoT Hub SAS Telemetry Sample

  • Executable: paho_iot_hub_sas_telemetry_sample

    This sample sends five telemetry messages to the Azure IoT Hub. SAS authentication is used.

IoT Hub Twin Sample

  • Executable: paho_iot_hub_twin_sample

    This sample utilizes the Azure IoT Hub to get the device twin document, send a reported property message, and receive up to 5 desired property messages. If a timeout occurs while waiting for a message from the Azure IoT Hub, the sample will exit. Upon receiving a desired property message, the sample will update the twin property locally and send a reported property message back to the service. X509 authentication is used.

    How to interact with the Twin sample:

    A desired property named device_count is supported for this sample.

    To send a device twin desired property message: Select your device's "Device Twin" tab in the Azure Portal of your IoT Hub. Add the property device_count along with a corresponding value to the desired section of the JSON. Select "Save" to update the twin document and send the twin message to the device.

    "properties": {
        "desired": {
            "device_count": 42,
        }
    }

    No other property names sent in a desired property message are supported. If any are sent, the log will report there is nothing to update.

IoT Plug and Play Sample

This sample connects an IoT Plug and Play enabled device (a thermostat) with the Digital Twin Model ID (DTMI) detailed here. If a timeout occurs while waiting for a message from the Azure IoT Explorer, the sample will continue. If 3 timeouts occur consecutively, the sample will disconnect. X509 authentication is used.

How to interact with the IoT Plug and Play sample:

The easiest way to interact with this sample from the service side is to use Azure IoT Explorer. To use the sample:

  • Follow the initial setup instructions described above.
  • Install Azure IoT Explorer.
  • Download the Thermostat model to a local directory.
  • Build and run paho_iot_pnp_sample.
  • Start Azure IoT Explorer and then:
    • Configure your hub. Once you've created your thermostat device, you should see it listed in the UX.
    • Go to IoT Plug and Play Settings on the home screen, select Local Folder for the location of the model definitions, and point to the folder you downloaded the thermostat model.
    • Go to the devices list and select your thermostat device. Now select IoT Plug and Play components and then Default Component.
    • You will now be able to interact with the IoT Plug and Play device.

Additional instructions for Azure IoT Explorer, including screenshots, are available here.

IoT Plug and Play with Provisioning Sample

  • Executable: paho_iot_pnp_with_provisioning_sample

    This sample has the same functionality as the paho_iot_pnp_sample but uses the Azure Device Provisioning Service for authentication. The same steps above should be followed for interacting with the sample in Azure IoT Explorer.

IoT Plug and Play Multiple Component Sample

This sample connects an IoT Plug and Play enabled device simulating a temperature controller directly to Azure IoT Hub. This device is described via the Digital Twin Model ID (DTMI) detailed here. X509 authentication is used.

This Temperature Controller is made up of multiple components. These are implemented in the ./pnp subdirectory.

How to interact with the IoT Plug and Play Multiple Component sample:

The easiest way to interact with this sample from the service side is to use Azure IoT Explorer. To use the sample:

  • Follow the initial setup instructions described above.

  • Install Azure IoT Explorer.

  • Download the Temperature Controller model to a local directory.

  • Build and run paho_iot_pnp_component_sample.

  • Start Azure IoT Explorer and then:

    • Configure your hub. Once you've created your thermostat device, you should see it listed in the UX.
    • Go to IoT Plug and Play Settings on the home screen, select Local Folder for the location of the model definitions, and point to the folder you downloaded the thermostat model.
    • Go to the devices list and select your thermostat device. Now select IoT Plug and Play components and then Default Component.
    • You will now be able to interact with the IoT Plug and Play device.

    Additional instructions for Azure IoT Explorer, including screenshots, are available here.

IoT Provisioning Certificate Sample

  • Executable: paho_iot_provisioning_sample

    This sample registers a device with the Azure IoT Device Provisioning Service. It will wait to receive the registration status before disconnecting. X509 authentication is used.

IoT Provisioning SAS Sample

  • Executable: paho_iot_provisioning_sas_sample

    This sample registers a device with the Azure IoT Device Provisioning Service. It will wait to receive the registration status before disconnecting. SAS authentication is used.

Using IoT Hub with an ECC Server Certificate Chain

To work with the new Azure Cloud ECC server certificate chain, the TLS stack must be configured to prevent RSA cipher-suites from being advertised, as described here.

When using Paho MQTT for C, modify the samples by adding the following TLS option:

mqtt_ssl_options.enabledCipherSuites = "ECDH+ECDSA+HIGH";

Next Steps and Additional Documentation

Start using the Azure Embedded C SDK IoT Clients in your solutions!

Troubleshooting

  • The error policy for the Embedded C SDK client library is documented here.
  • File an issue via Github Issues.
  • Check previous questions or ask new ones on StackOverflow using the azure and c tags.

Contributing

This project welcomes contributions and suggestions. Find more contributing details here.

License

Azure SDK for Embedded C is licensed under the MIT license.