diff --git a/usermods/usermod_v2_HttpPullLightControl/readme.md b/usermods/usermod_v2_HttpPullLightControl/readme.md index 3faff65a..cf7f971f 100644 --- a/usermods/usermod_v2_HttpPullLightControl/readme.md +++ b/usermods/usermod_v2_HttpPullLightControl/readme.md @@ -17,7 +17,7 @@ The `usermod_v2_HttpPullLightControl` is a custom user module for WLED that enab * Specify the URL endpoint and polling interval. ## JSON Format and examples -* The module sends a GET request to the configured URL, appending a unique identifier as a query parameter: `https://www.example.com/mycustompage.php?id=xxxxxxxx` where xxxxxxx is a hash of the MAC address combined with a given salt. +* The module sends a GET request to the configured URL, appending a unique identifier as a query parameter: `https://www.example.com/mycustompage.php?id=xxxxxxxx` where xxxxxxx is a 40 character long SHA1 hash of the MAC address combined with a given salt. * Response Format (since v0.0.3) it is eactly the same as the WLED JSON API, see: https://kno.wled.ge/interfaces/json-api/ After getting the URL (it can be a static file like static.json or a mylogic.php which gives a dynamic response), the response is read and parsed to WLED. diff --git a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.cpp b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.cpp index ac11f56b..5cd89e77 100644 --- a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.cpp +++ b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.cpp @@ -24,6 +24,8 @@ void HttpPullLightControl::setup() { // Go on with generating a unique ID and splitting the URL into parts uniqueId = generateUniqueId(); // Cache the unique ID + DEBUG_PRINT(F("UniqueId calculated: ")); + DEBUG_PRINTLN(uniqueId); parseUrl(); DEBUG_PRINTLN(F("HttpPullLightControl successfully setup")); } @@ -42,20 +44,51 @@ void HttpPullLightControl::loop() { // Generate a unique ID based on the MAC address and a SALT String HttpPullLightControl::generateUniqueId() { - // We use an easy to implement Fowler–Noll–Vo hash function so we dont need any Sha1.h or Crypto.h dependencies uint8_t mac[6]; WiFi.macAddress(mac); char macStr[18]; sprintf(macStr, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - String input = String(macStr) + salt; - unsigned long hashValue = FNV_offset_basis; - for (char c : input) { - hashValue *= FNV_prime; - hashValue ^= c; - } - DEBUG_PRINT(F("Unique ID generated: ")); - DEBUG_PRINTLN(hashValue); - return String(hashValue); + // Set the MAC Address to a string and make it UPPERcase + String macString = String(macStr); + macString.toUpperCase(); + DEBUG_PRINT(F("WiFi MAC address is: ")); + DEBUG_PRINTLN(macString); + DEBUG_PRINT(F("Salt is: ")); + DEBUG_PRINTLN(salt); + String input = macString + salt; + + #ifdef ESP8266 + // For ESP8266 we use the Hash.h library which is built into the ESP8266 Core + return sha1(input); + #endif + + #ifdef ESP32 + // For ESP32 we use the mbedtls library which is built into the ESP32 core + int status = 0; + unsigned char shaResult[20]; // SHA1 produces a hash of 20 bytes (which is 40 HEX characters) + mbedtls_sha1_context ctx; + mbedtls_sha1_init(&ctx); + status = mbedtls_sha1_starts_ret(&ctx); + if (status != 0) { + DEBUG_PRINTLN(F("Error starting SHA1 checksum calculation")); + } + status = mbedtls_sha1_update_ret(&ctx, reinterpret_cast(input.c_str()), input.length()); + if (status != 0) { + DEBUG_PRINTLN(F("Error feeding update buffer into ongoing SHA1 checksum calculation")); + } + status = mbedtls_sha1_finish_ret(&ctx, shaResult); + if (status != 0) { + DEBUG_PRINTLN(F("Error finishing SHA1 checksum calculation")); + } + mbedtls_sha1_free(&ctx); + + // Convert the Hash to a hexadecimal string + char buf[41]; + for (int i = 0; i < 20; i++) { + sprintf(&buf[i*2], "%02x", shaResult[i]); + } + return String(buf); + #endif } // This function is called when the user updates the Sald and so we need to re-calculate the unique ID @@ -63,6 +96,8 @@ void HttpPullLightControl::updateSalt(String newSalt) { DEBUG_PRINTLN(F("Salt updated")); this->salt = newSalt; uniqueId = generateUniqueId(); + DEBUG_PRINT(F("New UniqueId is: ")); + DEBUG_PRINTLN(uniqueId); } // The function is used to separate the URL in a host part and a path part diff --git a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h index ae93a193..5f346f4d 100644 --- a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h +++ b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h @@ -1,7 +1,7 @@ #pragma once /* * Usermod: HttpPullLightControl - * Versie: 0.0.3 + * Versie: 0.0.4 * Repository: https://github.com/roelbroersma/WLED-usermodv2_HttpPullLightControl * Author: Roel Broersma * Website: https://www.roelbroersma.nl @@ -19,7 +19,16 @@ #include "wled.h" -#define HTTP_PULL_LIGHT_CONTROL_VERSION "0.0.3" +// Use the following for SHA1 computation of our HASH, unfortunatelly PlatformIO doesnt recognize Hash.h while its already in the Core. +// We use Hash.h for ESP8266 (in the core) and mbedtls/sha256.h for ESP32 (in the core). +#ifdef ESP8266 + #include +#endif +#ifdef ESP32 + #include "mbedtls/sha1.h" +#endif + +#define HTTP_PULL_LIGHT_CONTROL_VERSION "0.0.4" class HttpPullLightControl : public Usermod { private: