Checksum OTA

1.3mb kết hợp cách này cahwcs là ổn

Cách Kiểm Tra Checksum Firmware OTA Không Cần Filesystem

Kiểm tra checksum (SHA256/MD5) khi tải firmware OTA mà không cần lưu vào filesystem (SPIFFS/LittleFS). Dưới đây là 3 phương pháp khả thi:


1. Tính Checksum Trực Trên Dòng Dữ Liệu (Streaming)

Ưu điểm:

  • Không tốn bộ nhớ lưu trữ

  • Vẫn đảm bảo tính toàn vẹn firmware

Code Mẫu (Arduino + HTTP):

cpp

Copy

#include <HTTPClient.h>
#include <Update.h>
#include <SHA256.h>

void performOTAWithChecksum() {
  HTTPClient http;
  http.begin("http://your-server/firmware.bin");
  
  // Yêu cầu server gửi kèm checksum (qua header)
  http.addHeader("X-Checksum-Request", "SHA256");
  
  int httpCode = http.GET();
  if (httpCode == HTTP_CODE_OK) {
    // Nhận checksum từ server (ví dụ: "a1b2c3...")
    String serverChecksum = http.header("X-Firmware-Checksum");
    
    // Khởi tạo SHA256
    SHA256 sha256;
    sha256.begin();
    
    // Bắt đầu OTA
    int firmwareSize = http.getSize();
    if (Update.begin(firmwareSize)) {
      WiFiClient *stream = http.getStreamPtr();
      uint8_t buffer[512];
      size_t totalRead = 0;
      
      // Đọc từng chunk và cập nhật checksum
      while (http.connected() && (totalRead < firmwareSize)) {
        size_t bytesRead = stream->readBytes(buffer, sizeof(buffer));
        sha256.update(buffer, bytesRead);  // Cập nhật checksum
        Update.write(buffer, bytesRead);   // Ghi trực tiếp vào OTA partition
        totalRead += bytesRead;
      }
      
      // Hoàn thành checksum
      uint8_t hash[32];
      sha256.end(hash);
      
      // Chuyển hash sang dạng hex string
      String localChecksum;
      for (int i = 0; i < 32; i++) {
        char str[3];
        sprintf(str, "%02x", hash[i]);
        localChecksum += str;
      }
      
      // So sánh với checksum từ server
      if (serverChecksum.equalsIgnoreCase(localChecksum)) {
        Serial.println("Checksum matched! Finalizing update...");
        if (Update.end() && Update.isFinished()) {
          ESP.restart();
        }
      } else {
        Serial.println("Checksum mismatch! Aborting...");
        Update.abort();
      }
    }
  }
  http.end();
}

2. Dùng "Two-Pass" OTA (Tải 2 Lần)

Ưu điểm:

  • Kiểm tra checksum trước khi áp dụng

  • Không cần filesystem

Cách hoạt động:

  1. Lần 1: Tải firmware để tính checksum (không ghi vào flash).

  2. Lần 2: Tải lại và ghi vào OTA partition nếu checksum khớp.

Code Tối Ưu:

cpp

Copy

bool verifyFirmwareChecksum(const char* url, const char* expectedChecksum) {
  HTTPClient http;
  http.begin(url);
  int httpCode = http.GET();
  
  if (httpCode == HTTP_CODE_OK) {
    SHA256 sha256;
    sha256.begin();
    
    WiFiClient *stream = http.getStreamPtr();
    uint8_t buffer[256];
    while (http.connected()) {
      size_t bytesRead = stream->readBytes(buffer, sizeof(buffer));
      sha256.update(buffer, bytesRead);
    }
    
    uint8_t hash[32];
    sha256.end(hash);
    
    String localChecksum;
    for (int i = 0; i < 32; i++) {
      char str[3];
      sprintf(str, "%02x", hash[i]);
      localChecksum += str;
    }
    
    http.end();
    return (localChecksum.equalsIgnoreCase(expectedChecksum));
  }
  http.end();
  return false;
}

void safeOTAUpdate() {
  const char* firmwareUrl = "http://server/firmware.bin";
  const char* expectedChecksum = "a1b2c3..."; // Nhận từ server trước
  
  // Bước 1: Kiểm tra checksum
  if (verifyFirmwareChecksum(firmwareUrl, expectedChecksum)) {
    // Bước 2: Tải và ghi vào OTA partition
    performDirectOTA(firmwareUrl); // Dùng hàm ở phần trước
  } else {
    Serial.println("Checksum verification failed!");
  }
}

3. Dùng "Delta OTA" (Chỉ Tải Phần Thay Đổi)

Ưu điểm:

  • Giảm dung lượng tải về → Giảm rủi ro checksum sai

  • Phù hợp firmware lớn (>1.5MB)

Cách triển khai:

  1. Server tính toán diff giữa firmware hiện tại và mới.

  2. ESP32 tải diff, áp dụng patch và kiểm tra checksum.

Thư viện hỗ trợ:

  • libxdelta3 (Cần port sang ESP32)

  • Tự triển khai thuật toán bsdiff


So Sánh Các Phương Pháp

Phương Pháp

Tốc Độ

Bộ Nhớ

Độ Tin Cậy

Phức Tạp

Streaming Checksum

⚡ Nhanh

📦 Thấp

⭐⭐

Dễ

Two-Pass OTA

🐢 2 lần tải

📦 Thấp

⭐⭐⭐

Trung bình

Delta OTA

⚡⚡ Rất nhanh

📦📦 Cao

⭐⭐⭐⭐

Khó


Lời Khuyên

  1. Nếu firmware <1MB: Dùng Streaming Checksum (cân bằng giữa tốc độ và độ tin cậy).

  2. Nếu firmware lớn (>1.5MB): Dùng Two-Pass OTA hoặc Delta OTA.

  3. Luôn yêu cầu server gửi checksum qua header HTTP.

Updated on