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

167 lines
6.7 KiB
Markdown

# 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](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](esp32/include/filesystem_ws.h)**: Handler class definition with transfer state management
- **[esp32/src/filesystem_ws.cpp](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](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](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](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](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
- **[FILESYSTEM_SVELTE_MIGRATION.md](FILESYSTEM_SVELTE_MIGRATION.md)**: Detailed migration guide
- **[FILESYSTEM_IMPLEMENTATION_COMPLETE.md](FILESYSTEM_IMPLEMENTATION_COMPLETE.md)**: This file
## 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)