diff --git a/.github/workflows/Build-Run.yml b/.github/workflows/Build-Run.yml index 6d05c33..83d464c 100644 --- a/.github/workflows/Build-Run.yml +++ b/.github/workflows/Build-Run.yml @@ -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 diff --git a/.gitignore b/.gitignore index 672b633..aabf35d 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,6 @@ uv2csolution.log # legacy intermediate project file *.cprj + +# Demo configuration file with secrets +FreeRTOS-Plus/Demo/Config/demo_config.h diff --git a/.vscode.d/tasks.json b/.vscode.d/tasks.json index 6018a9d..8e8ad38 100644 --- a/.vscode.d/tasks.json +++ b/.vscode.d/tasks.json @@ -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" diff --git a/FreeRTOS-Plus/Demo/Config/demo_config.h b/FreeRTOS-Plus/Demo/Config/demo_config_template.h similarity index 100% rename from FreeRTOS-Plus/Demo/Config/demo_config.h rename to FreeRTOS-Plus/Demo/Config/demo_config_template.h diff --git a/README.md b/README.md index 67a9631..3146947 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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. diff --git a/scripts/configure-aws-iot-thing.js b/scripts/configure-aws-iot-thing.js index a168ae6..b5a8977 100644 --- a/scripts/configure-aws-iot-thing.js +++ b/scripts/configure-aws-iot-thing.js @@ -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 +// Usage: node configure-aws-iot-thing.js 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 "); + throw new Error("Missing file path arguments! \nUsage: node configure-aws-iot-thing.js "); } - 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) @@ -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"))], @@ -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) {