Skip to content
Open
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
10 changes: 10 additions & 0 deletions firmware/include/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,13 @@ constexpr int MQTT_PACKET_SIZE = 1024;
constexpr int TOKEN_LIFESPAN = 1 * 60 * 60; // [sec.]
constexpr float RECONNECT_RATE = 0.85;
constexpr int JSON_MAX_SIZE = 1024;

// Edge Impulse Ingestion Settings
#define EDGE_IMPULSE_API_KEY "oLQEPYfKqMqGM8r"
#define EDGE_IMPULSE_DEVICE_ID "13:51:F2:11:53:54:4C:32:57:20:20:20:FF:06:1F:08"
#define EDGE_IMPULSE_DEVICE_TYPE "DATA_FORWARDER"
#define EDGE_IMPULSE_LABEL "gas_batch_training"
#define EDGE_IMPULSE_SENSOR_INTERVAL_MS 100
#define EDGE_IMPULSE_BATCH_SIZE 100
#define EDGE_IMPULSE_INGESTION_HOST "ingestion.edgeimpulse.com"
#define EDGE_IMPULSE_INGESTION_PATH_TRAINING "/api/training/data"
13 changes: 13 additions & 0 deletions firmware/include/CryptoUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <string>

/**
* @brief Computes the HMAC SHA256 hash of a message using a secret key.
*
* @param secret_key The secret key for the HMAC operation.
* @param message The message to hash.
* @return std::string The computed HMAC SHA256 hash as a lowercase hexadecimal string.
* Returns an empty string if an error occurs during computation.
*/
std::string compute_hmac_sha256(const char* secret_key, const char* message);
1 change: 1 addition & 0 deletions firmware/include/Storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Storage
std::string IdScope;
std::string RegistrationId;
std::string SymmetricKey;
std::string EdgeImpulseHmacKey;

Storage(ExtFlashLoader::QSPIFlash& flash);
void Load();
Expand Down
4 changes: 2 additions & 2 deletions firmware/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
; https://docs.platformio.org/page/projectconf.html

[env:seeed_wio_terminal]
platform = atmelsam @ 8.0.0
platform = atmelsam @ 8.3.0
board = seeed_wio_terminal
framework = arduino
platform_packages =
Expand Down Expand Up @@ -48,4 +48,4 @@ lib_deps =
knolleary/PubSubClient
hideakitai/MsgPack
bblanchon/ArduinoJson@6.20.1
; END Azure IoT dependencies
; END Azure IoT dependencies
20 changes: 19 additions & 1 deletion firmware/src/ConfigurationMode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ static void az_idscope_command(int argc, char** argv);
static void az_regid_command(int argc, char** argv);
static void az_symkey_command(int argc, char** argv);
static void az_iotc_command(int argc, char** argv);
static void ei_hmackey_command(int argc, char** argv); // New command function declaration

static const struct console_command cmds[] =
{
Expand All @@ -48,7 +49,8 @@ static const struct console_command cmds[] =
{"set_az_idscope" , "Set id scope of Azure IoT DPS" , az_idscope_command },
{"set_az_regid" , "Set registration id of Azure IoT DPS" , az_regid_command },
{"set_az_symkey" , "Set symmetric key of Azure IoT DPS" , az_symkey_command },
{"set_az_iotc" , "Set connection information of Azure IoT Central", az_iotc_command }
{"set_az_iotc" , "Set connection information of Azure IoT Central", az_iotc_command },
{"set_ei_hmackey" , "Set Edge Impulse HMAC Key" , ei_hmackey_command } // New command entry
};

static const int cmd_count = sizeof(cmds) / sizeof(cmds[0]);
Expand Down Expand Up @@ -133,6 +135,7 @@ static void display_settings_command(int argc, char** argv)
Serial.print(String::format("Id scope of Azure IoT DPS = %s" DLM, Storage_->IdScope.c_str()));
Serial.print(String::format("Registration id of Azure IoT DPS = %s" DLM, Storage_->RegistrationId.c_str()));
Serial.print(String::format("Symmetric key of Azure IoT DPS = %s" DLM, Storage_->SymmetricKey.c_str()));
Serial.print(String::format("Edge Impulse HMAC Key = %s" DLM, Storage_->EdgeImpulseHmacKey.c_str())); // Display HMAC key
}

static void wifissid_command(int argc, char** argv)
Expand Down Expand Up @@ -221,6 +224,21 @@ static void az_iotc_command(int argc, char** argv)
Serial.print("Set connection information of Azure IoT Central successfully." DLM);
}

// New command function implementation
static void ei_hmackey_command(int argc, char** argv)
{
if (argc != 2)
{
Serial.print(String::format("ERROR: Usage: %s <HMAC Key>. Please provide the Edge Impulse HMAC Key." DLM, argv[0]));
return;
}

Storage_->EdgeImpulseHmacKey = argv[1];
Storage_->Save();

Serial.print("Set Edge Impulse HMAC Key successfully." DLM);
}

static bool CliGetInput(char* inbuf, int* bp)
{
if (inbuf == nullptr)
Expand Down
46 changes: 46 additions & 0 deletions firmware/src/CryptoUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "CryptoUtils.h"
#include <mbedtls/md.h>
#include <string.h> // For strlen
#include <vector>
#include <iomanip>
#include <sstream>

// Include Arduino.h for Serial output if needed for error logging
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

std::string compute_hmac_sha256(const char* secret_key, const char* message) {
const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
if (md_info == NULL) {
Serial.println("Error: Failed to get mbedtls_md_info_from_type for SHA256.");
return "";
}

unsigned char hmac_output[32]; // SHA256 output is 32 bytes

int ret = mbedtls_md_hmac(
md_info,
(const unsigned char*)secret_key,
strlen(secret_key),
(const unsigned char*)message,
strlen(message),
hmac_output
);

if (ret != 0) {
Serial.print("Error: mbedtls_md_hmac failed with error code: ");
Serial.println(ret);
return "";
}

std::ostringstream oss;
oss << std::hex << std::setfill('0');
for (int i = 0; i < sizeof(hmac_output); ++i) {
oss << std::setw(2) << static_cast<unsigned int>(hmac_output[i]);
}

return oss.str();
}
18 changes: 14 additions & 4 deletions firmware/src/Storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,44 @@ void Storage::Load()
IdScope.clear();
RegistrationId.clear();
SymmetricKey.clear();
EdgeImpulseHmacKey.clear();
}
else
{
MsgPack::Unpacker unpacker;
unpacker.feed(&FlashStartAddress[8], *(const uint32_t*)&FlashStartAddress[4]);

MsgPack::str_t str[5];
unpacker.deserialize(str[0], str[1], str[2], str[3], str[4]);
MsgPack::str_t str[6]; // Increased size to 6
// Attempt to deserialize 6 strings. If old data has 5, this might be an issue.
// A robust solution would check unpacker.parsed() or use versioning.
// For now, we assume it either works or EdgeImpulseHmacKey remains empty/default.
unpacker.deserialize(str[0], str[1], str[2], str[3], str[4], str[5]);

WiFiSSID = str[0].c_str();
WiFiPassword = str[1].c_str();
IdScope = str[2].c_str();
RegistrationId = str[3].c_str();
SymmetricKey = str[4].c_str();
if (str[5].size() > 0) { // Basic check if the 6th string was populated
EdgeImpulseHmacKey = str[5].c_str();
} else {
EdgeImpulseHmacKey = ""; // Default if not found or empty
}
}
}

void Storage::Save()
{
MsgPack::Packer packer;
{
MsgPack::str_t str[5];
MsgPack::str_t str[6]; // Increased size to 6
str[0] = WiFiSSID.c_str();
str[1] = WiFiPassword.c_str();
str[2] = IdScope.c_str();
str[3] = RegistrationId.c_str();
str[4] = SymmetricKey.c_str();
packer.serialize(str[0], str[1], str[2], str[3], str[4]);
str[5] = EdgeImpulseHmacKey.c_str(); // Add HMAC key
packer.serialize(str[0], str[1], str[2], str[3], str[4], str[5]); // Serialize 6 strings
}

std::vector<uint8_t> buf(4 + 4 + packer.size());
Expand Down
Loading