Files
SpotMicroESP32-Leika/FILESYSTEM_IMPLEMENTATION_COMPLETE.md
T
2026-01-22 20:38:27 +01:00

6.7 KiB

Chunked Filesystem Implementation - Complete

Summary

Successfully implemented a complete chunked file transfer system for ESP32 ↔ Client communication that works within the 1KB WebSocket limitation.

What Was Built

1. Protocol Definition (platform_shared/message.proto)

  • File: Represents a file entry with name and size
  • Directory: Represents a directory entry with name only
  • 16 New Messages: 8 request/response pairs for filesystem operations:
    • List directory contents
    • Download file (start + chunked transfer)
    • Upload file (start + chunked transfer)
    • Delete file/directory
    • Create directory
    • Cancel transfer

2. ESP32 Implementation

  • esp32/include/filesystem_ws.h: Handler class definition with transfer state management
  • esp32/src/filesystem_ws.cpp: Complete implementation (370+ lines)
    • Transfer state tracking with unique IDs
    • 1024-byte chunk size for WebSocket compatibility
    • Sequential chunk processing
    • 30-second timeout-based cleanup
    • LittleFS integration
  • esp32/src/main.cpp: Integration
    • 8 correlation handlers for filesystem operations
    • Cleanup task running every 5 seconds

3. Client Implementation

  • app/src/lib/filesystem/chunkedTransfer.ts: TypeScript client library (290+ lines)
    • uploadFile(): Send files in chunks with progress tracking
    • downloadFile(): Receive files in chunks
    • uploadFileFromBrowser(): Browser file picker integration
    • downloadFileAndSave(): Automatic browser download
    • listDirectory(), deleteFile(), createDirectory()
    • Progress callbacks for UI updates

4. UI Migration

  • app/src/routes/system/filesystem/FileSystem.svelte: Complete rewrite
    • Migrated from HTTP REST API to WebSocket chunked transfers
    • Real-time progress bars for uploads/downloads
    • Flat directory navigation (not limited to /config)
    • File editing in-browser
    • Upload/download files of any size
    • Create/delete files and directories

Key Technical Details

Chunk Size

  • 1024 bytes per chunk to work within ESP32 WebSocket limitations

Transfer Protocol

  1. Start Transfer: Client requests transfer, receives unique transfer ID
  2. Chunked Transfer: Sequential chunks sent with index and data
  3. Completion: Last chunk marked with is_last flag
  4. Cleanup: Automatic cleanup after 30 seconds of inactivity

Protobuf Configuration

  • platform_shared/message.options: Fixed-size arrays instead of callbacks
    • File.name: 256 bytes
    • Directory.name: 256 bytes
    • Transfer IDs: 64 bytes
    • Chunk data: 1024 bytes
    • Error messages: 128 bytes
    • Paths: 256 bytes

Build Status

ESP32 firmware builds successfully for esp32-wroom-camera environment

  • Flash usage: 54.7% (1,828,333 bytes)
  • RAM usage: 36.8% (120,440 bytes)

Fixed Issues

Issue 1: Protobuf Callback Types

  • Problem: Initial protobuf generation used pb_callback_t for strings and arrays
  • Solution: Added message.options file with max_size and max_count specifications
  • Result: Generated structs now use fixed-size arrays (char name[256], etc.)

Issue 2: Recursive Directory Structure

  • Problem: Initial Directory definition was recursive (contained repeated Directory)
  • Solution: Simplified Directory to only contain a name field
  • Rationale: We use flat directory listings, not recursive trees
  • Result: FSListResponse contains the lists, Directory is just metadata

Testing Checklist

  • List directory contents
  • Navigate into subdirectories
  • Navigate up to parent directory
  • Upload small file (< 1KB)
  • Upload large file (> 10KB) and verify progress bar
  • Download file and verify browser download
  • Edit file content and save
  • Create new file
  • Create new directory
  • Delete file
  • Delete directory
  • Verify error handling (invalid paths, etc.)

Documentation

Next Steps

  1. Flash firmware to ESP32 device
  2. Test all filesystem operations end-to-end
  3. Verify progress tracking works correctly
  4. Test with various file sizes and types
  5. Verify timeout and cleanup mechanisms work as expected

Architecture Diagram

┌─────────────────┐                    ┌──────────────────┐
│  Svelte Client  │                    │   ESP32 Device   │
│                 │                    │                  │
│  FileSystem.    │◄──────WebSocket───►│  FileSystemWS::  │
│  svelte         │    (1KB chunks)    │  fsHandler       │
│                 │                    │                  │
│  chunkedTransfer│                    │  filesystem_ws.  │
│  .ts            │                    │  cpp             │
└─────────────────┘                    └──────────────────┘
        │                                      │
        │                                      │
        ▼                                      ▼
  ┌──────────┐                          ┌──────────┐
  │ Browser  │                          │ LittleFS │
  │ File I/O │                          │          │
  └──────────┘                          └──────────┘

File Transfer Flow

Upload Flow

1. Client: uploadFileFromBrowser(path, file)
2. Client → ESP: FSUploadStartRequest { path, fileSize, chunkSize }
3. ESP → Client: FSUploadStartResponse { transferId }
4. For each chunk:
   Client → ESP: FSUploadChunkRequest { transferId, chunkIndex, data, isLast }
   ESP → Client: FSUploadChunkResponse { success }
5. ESP closes file and removes transfer state

Download Flow

1. Client: downloadFileAndSave(path, filename)
2. Client → ESP: FSDownloadStartRequest { path }
3. ESP → Client: FSDownloadStartResponse { transferId, fileSize, chunkSize }
4. For each chunk:
   Client → ESP: FSDownloadChunkRequest { transferId, chunkIndex }
   ESP → Client: FSDownloadChunkResponse { transferId, data, isLast }
5. Client saves complete file to browser download

Status: Implementation Complete & Building Successfully Date: 2026-01-05 Build Environment: esp32-wroom-camera (ESP32-S3)