main.cpp
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <pgmspace.h>
 
// ===================== LAB CONFIG =====================
 
// Wi-Fi credentials
const char* WIFI_SSID     = "LAB_WIFI_SSID";
const char* WIFI_PASSWORD = "LAB_WIFI_PASSWORD";
 
// Server hostname and port.
// Hostname MUST match the CN/SAN in your server certificate (e.g. "iot-lab.local").
const char* SERVER_HOST   = "iot-lab.local";
const uint16_t SERVER_PORT = 8443;
 
// URL used by HTTPClient (hostname + port + path)
const char* SERVER_URL    = "https://iot-lab.local:8443/ingest";
 
// Device identity
const char* DEVICE_ID     = "sparrow-01";
 
// MAC secret key – must match SECRET_KEY in secure_server.py
const char* SECRET_KEY    = "LAB2_SUPER_SECRET_MAC_KEY";
 
// Root CA certificate (PEM), copied from ca.crt.
// Replace the placeholder contents with your actual CA cert.
static const char LAB_ROOT_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
PASTE_YOUR_CA_CERT_HERE
-----END CERTIFICATE-----
)EOF";
 
// ======================================================
 
WiFiClientSecure secureClient;
 
// Very simple, non-cryptographic MAC, must match server's compute_mac()
uint32_t computeMac(const String& payload, const char* secret) {
  String data = payload + secret;
  uint32_t h = 0;
  for (size_t i = 0; i < data.length(); i++) {
    uint8_t b = static_cast<uint8_t>(data[i]);
    h = (h * 31) ^ b;
  }
  return h;
}
 
void connectToWiFi() {
  Serial.printf("Connecting to WiFi SSID: %s\n", WIFI_SSID);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
 
  uint8_t retries = 0;
  while (WiFi.status() != WL_CONNECTED && retries < 30) {
    delay(500);
    Serial.print(".");
    retries++;
  }
 
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nWiFi connected!");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("\nFailed to connect to WiFi");
  }
}
 
void setup() {
  Serial.begin(115200);
  delay(2000);
 
  connectToWiFi();
 
  secureClient.setTimeout(15000);
 
  // Load CA certificate so the ESP32 can verify the server's cert.
  if (!secureClient.setCACert(LAB_ROOT_CA)) {
    Serial.println("Failed to load CA certificate!");
  } else {
    Serial.println("CA certificate loaded.");
  }
 
  randomSeed(esp_random());
}
 
void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi disconnected, reconnecting...");
    connectToWiFi();
  }
 
  if (WiFi.status() == WL_CONNECTED) {
    // Fake sensor data (same ranges as before)
    float tempC     = 20.0 + (random(0, 1000) / 100.0f);  // 20.00–29.99
    float humidity  = 40.0 + (random(0, 1000) / 50.0f);   // 40.0–59.9
    int   battery   = random(60, 100);                    // 60–99 %
 
    // Build JSON WITHOUT MAC first, in canonical key order:
    // battery, device_id, humidity, temp_c
    // This must match the server's json.dumps(sort_keys=True,separators=(",",":"))
    String jsonNoMac = "{";
    jsonNoMac += "\"battery\":" + String(battery) + ",";
    jsonNoMac += "\"device_id\":\"" + String(DEVICE_ID) + "\",";
    jsonNoMac += "\"humidity\":" + String(humidity, 1) + ",";
    jsonNoMac += "\"temp_c\":" + String(tempC, 2);
    jsonNoMac += "}";
 
    // Compute MAC over jsonNoMac + SECRET_KEY
    uint32_t mac = computeMac(jsonNoMac, SECRET_KEY);
 
    // Full JSON payload including MAC
    String payload = "{";
    payload += "\"battery\":" + String(battery) + ",";
    payload += "\"device_id\":\"" + String(DEVICE_ID) + "\",";
    payload += "\"humidity\":" + String(humidity, 1) + ",";
    payload += "\"temp_c\":" + String(tempC, 2) + ",";
    payload += "\"mac\":" + String(mac);
    payload += "}";
 
    Serial.println("Sending HTTPS POST to server (with cert validation)...");
    Serial.println("URL: " + String(SERVER_URL));
    Serial.println("Payload: " + payload);
 
    HTTPClient http;
 
    // Begin HTTPS connection with certificate verification.
    if (!http.begin(secureClient, SERVER_URL)) {
      Serial.println("Failed to start HTTP connection");
    } else {
      http.addHeader("Content-Type", "application/json");
 
      int httpCode = http.POST(payload);
      if (httpCode > 0) {
        Serial.printf("HTTP response code: %d\n", httpCode);
        String response = http.getString();
        Serial.println("Response body: " + response);
      } else {
        Serial.printf("HTTP POST failed, error: %s\n", http.errorToString(httpCode).c_str());
      }
 
      Serial.println("-----------------------------");
      http.end();
    }
  }
 
  delay(5000);  // send every 5 seconds
}
iothings/laboratoare/2025_code/lab8_3.txt · Last modified: 2025/11/15 13:21 by dan.tudose
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0