Skip to content
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
4 changes: 3 additions & 1 deletion .github/workflows/Build-Run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ jobs:
CLIENT_PRIVATE_KEY_PEM: ${{ secrets.CLIENT_PRIVATE_KEY_PEM }}

run: |
node ./scripts/configure-aws-iot-thing.js ./FreeRTOS-Plus/Demo/Config/demo_config.h
node ./scripts/configure-aws-iot-thing.js \
./FreeRTOS-Plus/Demo/Config/demo_config_template.h \
./FreeRTOS-Plus/Demo/Config/demo_config.h

# Build the executable
- name: Build executable
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,6 @@ uv2csolution.log

# legacy intermediate project file
*.cprj

# Demo configuration file with secrets
FreeRTOS-Plus/Demo/Config/demo_config.h
3 changes: 2 additions & 1 deletion .vscode.d/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"type": "shell",
"command": "node",
"args": [
"scripts/configure-aws-iot-thing.js",
"./scripts/configure-aws-iot-thing.js",
"./FreeRTOS-Plus/Demo/Config/demo_config_template.h",
"./FreeRTOS-Plus/Demo/Config/demo_config.h"
],
"group": "build"
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ This demo application connects to **AWS MQTT broker** using TLS with mutual auth
It demonstrates the subscribe-publish workflow of MQTT.

Visit [*coreMQTT Demo (Mutual Authentication)*](https://www.freertos.org/Documentation/03-Libraries/03-FreeRTOS-core/02-coreMQTT/02-Demos/03-Mutual-authentication) for further information.
Please note, that [*properly configured thing*](https://docs.aws.amazon.com/iot/latest/developerguide/iot-moisture-create-thing.html) is required to
Please note, that a [*properly configured thing*](https://docs.aws.amazon.com/iot/latest/developerguide/iot-moisture-create-thing.html) is required to
successfully run the demo application.

## Requirements

- [AWS Account](https://aws.amazon.com/free) to connect an [*AWS IoT Thing*](https://docs.aws.amazon.com/iot/latest/developerguide/iot-moisture-create-thing.html).
- [AWS Account](https://aws.amazon.com/free) to [create the *AWS IoT Thing*](https://docs.aws.amazon.com/iot/latest/developerguide/iot-moisture-create-thing.html).
- A CMSIS-Toolbox enabled toolchain such as [Keil Studio for VS Code](https://www.keil.arm.com/). The [MDK Community Edition](https://www.keil.arm.com/keil-mdk/#mdk-v6-editions) provides all tools required for evaluation.

## Project Structure
Expand All @@ -32,19 +32,20 @@ Project File | D

## Configure AWS IoT Thing

To run the demo application [*configure the AWS IoT Thing*](https://docs.aws.amazon.com/iot/latest/developerguide/iot-moisture-create-thing.html) with these steps:
After [creating the *AWS IoT Thing*](https://docs.aws.amazon.com/iot/latest/developerguide/iot-moisture-create-thing.html), the demo application needs to be configured with the relevant information of the AWS IoT Thing. This is done by updating the placeholder definitions in the configuration file.

- Modify the following definitions in [FreeRTOS-Plus/Demo/Config/demo_config.h](FreeRTOS-Plus/Demo/Config/demo_config.h):
- Copy the file [FreeRTOS-Plus/Demo/Config/demo_config_template.h](FreeRTOS-Plus/Demo/Config/demo_config_template.h) to `FreeRTOS-Plus/Demo/Config/demo_config.h`.
- Modify the following definitions in `FreeRTOS-Plus/Demo/Config/demo_config.h`:
- `democonfigCLIENT_IDENTIFIER`: Thing Name (AWS IoT->Manage->Things->Name in AWS IoT console)
- `democonfigMQTT_BROKER_ENDPOINT`: Remote Host Address (AWS IoT->Settings in AWS IoT console)
- `democonfigROOT_CA_PEM`: Server's root CA Certificate
- `democonfigCLIENT_CERTIFICATE_PEM`: Client Certificate
- `democonfigCLIENT_PRIVATE_KEY_PEM`: Client Private Key

Rather than modifying the definitions manually, you can provide AWS IoT Thing information through [environment variables](.doc/EnvVars.md) and run the script [configure-aws-iot-thing.js](scripts/configure-aws-iot-thing.js). The script updates the relevant defines in the [demo_config.h](FreeRTOS-Plus/Demo/Config/demo_config.h) based on those environment variables. This approach keeps configuration consistent across local development, CI runs on GitHub runners, and cloud environments such as GitHub Codespaces. Ensure that the relevant [environment variables](.doc/EnvVars.md) are correctly set and execute the script with:
Rather than copying the template and modifying the definitions manually, you can provide AWS IoT Thing information through [environment variables](.doc/EnvVars.md) and run the script [configure-aws-iot-thing.js](scripts/configure-aws-iot-thing.js). The script updates the relevant defines based on those environment variables. This approach keeps configuration consistent across local development, CI runs on GitHub runners, and cloud environments such as GitHub Codespaces. Ensure that the relevant [environment variables](.doc/EnvVars.md) are correctly set and execute the script with:

```bash
node ./scripts/configure-aws-iot-thing.js ./FreeRTOS-Plus/Demo/Config/demo_config.h
node ./scripts/configure-aws-iot-thing.js ./FreeRTOS-Plus/Demo/Config/demo_config_template.h ./FreeRTOS-Plus/Demo/Config/demo_config.h
```

or run the task `Configure AWS IoT Thing` when using VS Code.
Expand Down
39 changes: 22 additions & 17 deletions scripts/configure-aws-iot-thing.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,39 @@
// CLIENT_CERTIFICATE_PEM - Client certificate (PEM format)
// CLIENT_PRIVATE_KEY_PEM - Client private key (PEM format)
//
// Usage: node configure-aws-iot-thing.js <path-to-demo_config.h>
// Usage: node configure-aws-iot-thing.js <input-file> <output-file>

const fs = require("node:fs");
const path = require("node:path");

let configFilePath;
let inputFilePath;
let outputFilePath;

function getConfigFilePathFromArgs()
function getFilePathsFromArgs()
{
const configPath = process.argv[2];
const inputPath = process.argv[2];
const outputPath = process.argv[3];

if (!configPath)
if (!inputPath || !outputPath)
{
throw new Error("Missing config file path argument. Usage: node configure-aws-iot-thing.js <path-to-demo_config.h>");
throw new Error("Missing file path arguments! \nUsage: node configure-aws-iot-thing.js <input-file> <output-file>");
}

const resolvedPath = path.resolve(process.cwd(), configPath);
const resolvedInputPath = path.resolve(process.cwd(), inputPath);

if (!fs.existsSync(resolvedPath))
if (!fs.existsSync(resolvedInputPath))
{
throw new Error(`Config file does not exist: ${resolvedPath}`);
throw new Error(`Input file does not exist: ${resolvedInputPath}`);
}

if (!fs.statSync(resolvedPath).isFile())
if (!fs.statSync(resolvedInputPath).isFile())
{
throw new Error(`Config path is not a file: ${resolvedPath}`);
throw new Error(`Input path is not a file: ${resolvedInputPath}`);
}

return resolvedPath;
const resolvedOutputPath = path.resolve(process.cwd(), outputPath);

return [resolvedInputPath, resolvedOutputPath];
}

function getEnvVariable(name)
Expand Down Expand Up @@ -94,14 +98,14 @@ function setDefine(content, name, value)
return content.replace(placeholderPattern, ` */\n#define ${name} ${value}`);
}

throw new Error(`Unable to locate placeholder for ${name} in ${configFilePath}.`);
throw new Error(`Unable to locate placeholder for ${name} in ${inputFilePath}.`);
}

try
{
console.log("AWS IoT Thing configuration based on environment variables...");

configFilePath = getConfigFilePathFromArgs();
[inputFilePath, outputFilePath] = getFilePathsFromArgs();

const definitions = [
["democonfigCLIENT_IDENTIFIER", formatStr(getEnvVariable("IOT_THING_NAME"))],
Expand All @@ -111,16 +115,17 @@ try
["democonfigCLIENT_PRIVATE_KEY_PEM", formatPEM(getEnvVariable("CLIENT_PRIVATE_KEY_PEM"))],
];

let content = fs.readFileSync(configFilePath, "utf8");
let content = fs.readFileSync(inputFilePath, "utf8");

for (const [name, value] of definitions)
{
content = setDefine(content, name, value);
}

fs.writeFileSync(configFilePath, content, "utf8");
fs.writeFileSync(outputFilePath, content, "utf8");

console.log(`Configured ${path.relative(process.cwd(), configFilePath)}`);
console.log(`Input: ${inputFilePath}`);
console.log(`Output: ${outputFilePath}`);
}
catch (error)
{
Expand Down