Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AzureEventGrid sample #138

Merged
merged 2 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,6 @@
[submodule "LittleFs_Encrypted_RemoteDisk/src/HighLevelApp/littlefs"]
path = LittleFs_Encrypted_RemoteDisk/src/HighLevelApp/littlefs
url = https://github.com/littlefs-project/littlefs.git
[submodule "AzureEventGrid/MQTT-C"]
path = AzureEventGrid/MQTT-C
url = https://github.com/LiamBindle/MQTT-C
17 changes: 17 additions & 0 deletions AzureEventGrid/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
BasedOnStyle: Google
IndentWidth: 4
---
Language: Cpp
AccessModifierOffset: -4
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
BreakBeforeBraces: WebKit
ColumnLimit: 100
DerivePointerAlignment: false
KeepEmptyLinesAtTheStartOfBlocks: true
PointerAlignment: Right
SortIncludes: false
SpacesBeforeTrailingComments: 1
IndentCaseLabels: false
27 changes: 27 additions & 0 deletions AzureEventGrid/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch for Azure Sphere High-Level Applications (gdb)",
"type": "azurespheredbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"partnerComponents": [],
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
11 changes: 11 additions & 0 deletions AzureEventGrid/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"cmake.generator": "Ninja",
"cmake.buildDirectory": "${workspaceRoot}/out/ARM-${buildType}",
"cmake.buildToolArgs": [ "-v" ],
"cmake.configureSettings": {
"CMAKE_TOOLCHAIN_FILE": "${command:azuresphere.AzureSphereSdkDir}/CMakeFiles/AzureSphereToolchain.cmake",
"AZURE_SPHERE_TARGET_API_SET": "latest-lts"
},
"cmake.configureOnOpen": true,
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
}
51 changes: 51 additions & 0 deletions AzureEventGrid/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

cmake_minimum_required (VERSION 3.10)
project (AzureEventGrid_HighLevelApp C)

#
add_compile_definitions(MQTT_USE_WOLFSSL)
#
###################################################################################################################

add_library(mqttc STATIC
MQTT-C/src/mqtt_pal.c
MQTT-C/src/mqtt.c
)
include_directories(${CMAKE_SOURCE_DIR} MQTT-C/include)

# Create executable
add_executable (${PROJECT_NAME} main.c mqtt_connection.c eventloop_timer_utilities.c options.c)
target_link_libraries (${PROJECT_NAME} applibs pthread gcc_s c wolfssl tlsutils mqttc)

set_source_files_properties(MQTT-C/src/mqtt.c PROPERTIES COMPILE_FLAGS -Wno-conversion)
set_source_files_properties(MQTT-C/include/mqtt.h PROPERTIES COMPILE_FLAGS -Wno-sign-conversion)
set_source_files_properties(MQTT-C/src/mqtt_pal.c PROPERTIES COMPILE_FLAGS -Wno-conversion)

# Target hardware for the sample.
set(TARGET_HARDWARE "mt3620_rdb")
set(TARGET_DEFINITION "sample_appliance.json")

# Referencing the HardwareDefinitions directly from the SDK, so to not carry them over
azsphere_target_hardware_definition(${PROJECT_NAME} TARGET_DIRECTORY "${AZURE_SPHERE_SDK_PATH}/HardwareDefinitions" TARGET_DEFINITION "mt3620.json")

find_program(POWERSHELL powershell.exe)

if (POWERSHELL)
# Run validate_manifest script during build
add_custom_target(ValidateManifest ALL
COMMAND ${POWERSHELL} -ExecutionPolicy Bypass -NoProfile -NonInteractive
-File ${CMAKE_SOURCE_DIR}/script/validate_manifest.ps1
-Manifest ${CMAKE_SOURCE_DIR}/app_manifest.json
DEPENDS ${CMAKE_SOURCE_DIR}/app_manifest.json)
else()
# Warn users without PowerShell to update their manifest
add_custom_target(ValidateManifest ALL
COMMAND echo "Please ensure that you have updated app_manifest.json as described in README.md."
DEPENDS ${CMAKE_SOURCE_DIR}/app_manifest.json)
endif()

add_dependencies(ValidateManifest ${PROJECT_NAME})

azsphere_target_add_image_package(${PROJECT_NAME} RESOURCE_FILES "Certs/DigiCertGlobalRootG2CA.pem")
30 changes: 30 additions & 0 deletions AzureEventGrid/CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"version": 2,
"configurePresets": [
{
"name": "ARM-Debug",
"displayName": "ARM-Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
"CMAKE_TOOLCHAIN_FILE": "$env{AzureSphereDefaultSDKDir}/CMakeFiles/AzureSphereToolchain.cmake",
"AZURE_SPHERE_TARGET_API_SET": "latest-lts"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"intelliSenseMode": "linux-gcc-arm"
}
}
},
{
"name": "ARM-Release",
"displayName": "ARM-Release",
"inherits": "ARM-Debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
]
}
22 changes: 22 additions & 0 deletions AzureEventGrid/Certs/DigiCertGlobalRootG2CA.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
-----END CERTIFICATE-----
1 change: 1 addition & 0 deletions AzureEventGrid/MQTT-C
Submodule MQTT-C added at 7a986a
147 changes: 147 additions & 0 deletions AzureEventGrid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Project: Azure Sphere - Azure Event Grid

The goal of this project is to show how to connect an Azure Sphere device to the Azure Event Grid service to publish and subscribe to messages over MQTT v3.1.1 protocol, making use of Azure Sphere's [DAA certificates](https://learn.microsoft.com/azure-sphere/deployment/certificate-use-with-azure-sphere?view=azure-sphere-integrated#azure-sphere-devices) for secure, authenticated, and attested connectivity. This project uses the [MQTT-C](https://github.com/LiamBindle/MQTT-C) library to establish an MQTT v3.1.1 connection to Azure Event Grid.

This project both publishes and subscribes to the MQTT [topic space](https://learn.microsoft.com/azure/event-grid/mqtt-topic-spaces) `devices/${client.authenticationName}/telemetry`.

> **Note:** **This project is not intended as production-ready code and should be used only for evaluation purposes.** In particular we strongly recommend careful consideration of your own choice of MQTT client library for production use to ensure it meets your requirements, especially for ongoing security and maintenance. The open source MQTT-C library used here has been chosen because of its permissive MIT license, for easy evaluation of Azure Event Grid capability, and has not been evaluated for security and support in a production scenario.


## Prerequisites
1. The project requires the following hardware:

- An [Azure Sphere development board](https://aka.ms/azurespheredevkits) that supports the [Sample Appliance](../../../HardwareDefinitions) hardware requirements.

**Note:** By default, the project targets the [Reference Development Board](https://learn.microsoft.com/azure-sphere/hardware/mt3620-reference-board-design) design, which is implemented by the Seeed Studios MT3620 Development Board. To build the project for different Azure Sphere hardware, change the value of the TARGET_HARDWARE variable in the `CMakeLists.txt` file. For further information see [use hardware definitions](https://learn.microsoft.com/azure-sphere/app-development/manage-hardware-dependencies?view=azure-sphere-integrated)
1. MQTT-C library is included via a submodule. Ensure that you initialize, fetch and checkout submodules for this repo.
```
git submodule update --init --recursive
```
1. We encourage you to familiarize yourself with:
- The [MQTT-C documentation](https://github.com/LiamBindle/MQTT-C) to understand the MQTT-C library.
- [Event Grid overview](https://learn.microsoft.com/azure/event-grid/overview) before starting this project. Here is a helpful list of [terminologies](https://learn.microsoft.com/azure/event-grid/mqtt-event-grid-namespace-terminology) that explains the key terms relevant for Azure Event Grid.
1. An Azure subscription. If your organization does not already have a subscription, you can set up a [free trial subscription](https://azure.microsoft.com/free/?v=17.15).

## Setup
1. Ensure that your Azure Sphere device is connected to your computer, and your computer is connected to the internet.
1. Ensure that you have Azure Sphere SDK installed for [Windows](https://learn.microsoft.com/azure-sphere/install/install-sdk) or [Linux](https://learn.microsoft.com/azure-sphere/install/install-sdk-linux) as needed.
1. Ensure that the [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) is installed. At a minimum, the Azure CLI version must be 2.45.0 or later.
1. Install the [Azure Sphere extension](https://learn.microsoft.com/azure-sphere/reference/cli/overview?view=azure-sphere-integrated).
1. Enable application development, if you have not already done so, by entering the `az sphere device enable-development` command in the [command prompt](https://learn.microsoft.com/azure-sphere/reference/cli/overview?view=azure-sphere-integrated).
1. If you don't already have openSSL, you can download a recommended installation package from [openssl.org’s official wiki page]( https://wiki.openssl.org/index.php/Binaries) and install it your PC.

## Setup your project
1. Create an Azure Event Grid instance in the Azure portal.
Follow the [instructions to create a namespace](https://learn.microsoft.com/azure/event-grid/mqtt-publish-and-subscribe-portal#create-a-namespace) to create an Event Grid instance.

1. Upload the catalog CA certificate.

Azure Event Grid's MQTT broker supports certificate-based authentication to establish a secure connection.
1. [Download the catalog CA certificate](https://learn.microsoft.com/azure-sphere/deployment/az-certificate-download?view=azure-sphere-integrated) using the portal or the Azure Sphere Extension for the Azure CLI.
1. Convert the certificate to PEM format using the following command:

```
openssl x509 -in CAcertificate.cer -out CAcertificate.pem
```

1. Follow these instructions to [upload the catalog CA certificate to Azure Event Grid](https://learn.microsoft.com/azure/event-grid/mqtt-certificate-chain-client-authentication#upload-the-ca-certificate-to-the-namespace).

Refer to [MQTT client authentication using certificates](https://learn.microsoft.com/azure/event-grid/mqtt-client-certificate-authentication) for more information.

1. Configure the client authentication settings in Azure Event Grid.

Azure Event Grid's MQTT broker supports authentication of clients using X.509 certificates.

Follow these instructions to [configure client authentication](https://learn.microsoft.com/azure/event-grid/mqtt-certificate-chain-client-authentication#configure-client-authentication-settings).

- **Client Name** - Set a name for the client. If you prefer, the client name can be different from the Client Authentication Name.
- **Client Authentication Name** - Set the device ID of your Azure Sphere device as the client authentication name. Run the [`az sphere device show-attached`](https://learn.microsoft.com/en-gb/azure-sphere/reference/cli/azsphere-device?view=azure-sphere-integrated#az-sphere-device-show-attached) command to obtain the Device ID.
- **Client Certificate Authentication Validation Scheme** - Set to "Subject Matches Authentication Name".


![Add Client](images/add-client.png)


Refer to [MQTT clients](https://learn.microsoft.com/azure/event-grid/mqtt-clients) for more information.

1. Create a topic space in the Event Grid instance.

Topic space is a set of topic templates. It's used to simplify access control management by enabling you to scope publish or subscribe access for a client group, to a group of topics at once instead of individual topics.

Follow these instructions to [create a topic space](https://learn.microsoft.com/azure/event-grid/mqtt-publish-and-subscribe-portal#create-topic-spaces).
- Provide any name for the topic space, for example `telemetry-topic-space`.
- Use `devices/${client.authenticationName}/telemetry` as the topic template for this sample.
This sample uses granular access control to control the authorization of each client. Refer to [granular access control](https://learn.microsoft.com/azure/event-grid/mqtt-access-control#granular-access-control) for further information.

![Create Topic Space](images/create-topic-space.png)

Refer to [topic spaces](https://learn.microsoft.com/azure/event-grid/mqtt-topic-spaces) for more information.

1. Create permission bindings
A permission binding grants access to a specific client group to either publish or subscribe on a specific topic space. Follow these instructions to [create permission bindings](https://learn.microsoft.com/azure/event-grid/mqtt-publish-and-subscribe-portal#configuring-access-control-using-permission-bindings).

**Note:** Make sure to set both Publisher and Subscriber permission bindings.

- Publisher binding:

![Permission binding - Publisher](images/publisher-binding.png)

- Subscriber binding:

![Permission binding - Subscriber](images/subscriber-binding.png)

Refer to [Access control for MQTT clients](https://learn.microsoft.com/azure/event-grid/mqtt-access-control) for more information on permission bindings.

### Modify the project Application Manifest
Update the following items in the application manifest:
1. **CmdArgs** field of the app_manifest.json file:
- In the Azure portal, from the overview section of the Event Grid instance, copy the "MQTT hostname"" and replace `<your_event_grid_mqtt_hostname>` in the **CmdArgs** field of the app_manifest.json file with the value of your MQTT hostname. Your **CmdArgs** field should now look like:

`"CmdArgs": [ "--Hostname", "<your_event_grid_mqtt_hostname.ts.eventgrid.azure.net>" ]`
1. **AllowedConnections** field of the app_manifest.json file.From the overview section of the Event Grid instance, copy the "MQTT hostname" and replace `<your_event_grid_mqtt_hostname>` in the `AllowedConnections` section of the `app_manifest.json` file.
- Copy the hostname used in the **CmdArgs** field and append it to the **AllowedConnections** field of the app_manifest.json file. The field should now look like:

`"AllowedConnections": [ "<your_event_grid_mqtt_hostname.ts.eventgrid.azure.net>" ]`
1. **DeviceAuthentication** field of the app_manifest.json file.

- [Retrieve your catalog details](https://learn.microsoft.com/azure-sphere/deployment/az-catalog-show?view=azure-sphere-integrated) to get the Azure Sphere Catalog ID. Use the GUID, not the friendly name, and paste it into the **DeviceAuthentication** field of the app_manifest.json file:

- Your **DeviceAuthentication** field should now look like:

`"DeviceAuthentication": "<GUID>"`

## How to use the project
Build and run the project. The project publishes a simulated temperature to the topic `devices/$\{client.authenticationName\}/telemetry`. It also subscribes to the same topic, and hence receives the messages that are published.

## Project expectations

The code has been developed to show how to integrate Azure Event Grid into an Azure Sphere project - It is not official, maintained, or production-ready code.

### Expected support for the code

This code is not formally maintained, but we will make a best effort to respond to/address any issues you encounter.

### How to report an issue

If you run into an issue with this code, please open a GitHub issue against this repo.

## Contributing

This project welcomes contributions and suggestions. Most contributions require you to
agree to a Contributor License Agreement (CLA) declaring that you have the right to,
and actually do, grant us the rights to use your contribution. For details, visit
https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need
to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the
instructions provided by the bot. You will only need to do this once across all repositories using our CLA.

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
or contact [[email protected]](mailto:[email protected]) with any additional questions or comments.

## License

See [LICENSE.txt](./LICENSE.txt)

- MQTT-C is included via a submodule. The license for MQTT-C can be [found here](https://github.com/LiamBindle/MQTT-C/blob/master/LICENSE).
12 changes: 12 additions & 0 deletions AzureEventGrid/app_manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"SchemaVersion": 1,
"Name": "AzureEventGrid_HighLevelApp",
"ComponentId": "661F0FCE-25FF-421F-AFCD-542DD1CE5355",
"EntryPoint": "/bin/app",
"CmdArgs": [ "--Hostname", "<your_event_grid_mqtt_hostname>" ],
"Capabilities": {
"AllowedConnections": [ "<your_event_grid_mqtt_hostname>" ],
"DeviceAuthentication": "00000000-0000-0000-0000-000000000000"
},
"ApplicationType": "Default"
}
25 changes: 25 additions & 0 deletions AzureEventGrid/applibs_versions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

/// <summary>
/// This identifier should be defined before including any of the networking-related header files.
/// It indicates which version of the Wi-Fi data structures the application uses.
/// </summary>
#define NETWORKING_STRUCTS_VERSION 1

/// <summary>
/// This identifier must be defined before including any of the Wi-Fi related header files.
/// It indicates which version of the Wi-Fi data structures the application uses.
/// </summary>
#define WIFICONFIG_STRUCTS_VERSION 1

/// <summary>
/// This identifier must be defined before including any of the UART-related header files.
/// It indicates which version of the UART data structures the application uses.
/// </summary>
#define UART_STRUCTS_VERSION 1

/// <summary>
/// This identifier must be defined before including any of the SPI-related header files.
/// It indicates which version of the SPI data structures the application uses.
/// </summary>
#define SPI_STRUCTS_VERSION 1
Loading
Loading