Public Access
Storage: share the card with a phone's browser (#88)
`w` in the Storage App starts a small HTTP server and shows its address, as a QR code and in letters, with a six-digit code. A browser on the same network that has typed the code can list, download, upload, make folders and delete, under the Storage App's rules. The server runs only while that screen is open. Nothing is encrypted, and the screen says so. Uploads are streamed to the card under a temporary name and renamed when whole. Every access to the card is handed to the storage task, 8 KB at a time, from the server's own task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -298,3 +298,44 @@ Test pictures were copied to a scratch folder and removed afterwards, with the t
|
||||
**A decoder that worked once.** The library's PNG decoder showed the first picture and refused the next five: "no memory". It wants 44 KB in one piece, and after some use the largest piece is 43 to 47 KB. Writing a decoder that needs 32 KB was less work than it sounds, and unlike the library's it has tests.
|
||||
|
||||
**Two sentences still said "up to 16 KB"** about editing, in the README and the Storage guide, after issue #47 lifted that. Corrected here.
|
||||
|
||||
## Sharing the card with a browser (issue #88)
|
||||
|
||||
Files reached the card through the Debug Console's `put` and `get`, or by taking the card out. A phone has neither.
|
||||
|
||||
### Decisions (2026-10-07; the recommendation was accepted as it stood, without a round of questions)
|
||||
|
||||
- **A web page, not FTP, SFTP or WebDAV.** A browser is the only client every phone has. FTP and WebDAV need an app there; SFTP needs a whole SSH server here. WebDAV can come later on the same server, for computers.
|
||||
- **Off unless asked for:** `w` in the Storage App opens a "Share" screen, and the server runs only while that screen is open.
|
||||
- **A six-digit code on the screen**, new each time, typed in the page; the address is also a QR code, which carries the code. Five wrong codes close it for a minute (the Debug Console's `AuthGate`). A browser that got it right holds a cookie; starting again puts every browser out.
|
||||
- **Not encrypted.** A TLS server costs about 40 KB of memory a connection. The screen says so.
|
||||
- **The Storage App's rules** (`whyReadOnly`): the firmware's own folders, and files in use.
|
||||
|
||||
### As built
|
||||
|
||||
- **`WebShare`** (`src/services/web_share`): ESP-IDF's HTTP server, which is in the framework already. Seven requests: the page, the code, a listing as JSON, a download, an upload, a new folder, a delete.
|
||||
- **Every access to the card is handed to the storage task**, 8 KB at a time, from the server's own task: a download and an upload are loops of "one piece from the card, one piece to the network".
|
||||
- **An upload is the request's body**, as the browser's `PUT` sends it: no form to take apart. It goes to `<name>.part` and is renamed when the last byte has come; anything less is removed. A file that exists is refused unless the page asked, after asking the user.
|
||||
- **The page** (`web_share_page.h`) is one file of 5.4 KB with its style and script in it, served from flash.
|
||||
- **`lib/files/src/share_rules.h`** (host-tested, 5 tests): what a request names, which paths a browser may ask for (from the root, no `..`), the JSON, the code and the cookie.
|
||||
- **Cost:** 57 KB of flash, most of it the server. 13 KB of memory while sharing (108.4 KB free before, 95.4 with the screen open), given back on leaving.
|
||||
|
||||
### Checks on the device (2026-10-07 and 08)
|
||||
|
||||
A scratch folder was used and removed.
|
||||
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| `w` | The QR code, the address and the code; `share: on` on the console |
|
||||
| The page, and a listing without the code | 200; 401 |
|
||||
| A wrong code, the right one (typed `825 132`) | 403; in |
|
||||
| Upload, 2.6 MB | 11 to 17 s (150 to 230 KB/s); downloaded again and compared: the same, byte for byte |
|
||||
| The same name again; with "replace" | 409; replaced |
|
||||
| `..` in a path; deleting `/notes`; deleting a folder that isn't empty | 400; 403 "The firmware keeps its files in /notes"; 403 |
|
||||
| Five wrong codes | The fifth and every one after: 429, the right code too. A browser that was in stays in |
|
||||
| In Chromium at a phone's width | The scanned address logs in by itself; two files uploaded, one downloaded and compared, a folder made, a file deleted after asking, a replacement after asking, the refusal shown. No sideways scroll |
|
||||
| Back | The server is gone (connection refused), memory is back |
|
||||
|
||||
**Found on the way:** the server answers one request at a time. A second request during a slow download waited until it had ended. It is said in the guide, and not changed.
|
||||
|
||||
**Not checked:** a real phone, and its camera on the QR code. Safari. A card pulled during a transfer. Sharing with IRC connected, when memory is shorter. Home, and the screen turning off, while sharing (the code stops the server on leaving the App; only Back was tried).
|
||||
|
||||
@@ -59,6 +59,10 @@ Yes: it is [open source](https://git.twis.la/twisla/roro9stack) (GPL-3.0). The d
|
||||
|
||||
A secure connection takes about 52 KB of the 107 KB the device has, and IRC's takes about 40 KB. Both together do not always fit. See [When a connection says "not enough memory"](/howto/not-enough-memory/).
|
||||
|
||||
## How do I copy files to and from my phone?
|
||||
|
||||
In the Storage App, press <kbd>w</kbd>: the device serves a small web page to any browser on the same Wi-Fi. Scan the QR code it shows, type the code, and upload or download. Nothing to install. See [From a phone](/guide/storage/#from-a-phone).
|
||||
|
||||
## Do I need an SD card?
|
||||
|
||||
For the radio, GNSS position, Wi-Fi tools, IRC chat and Gemini browsing, no. For anything that is *kept*, yes: notes, IRC logs, Wi-Fi scan logs, GNSS Tracks, LoRa captures, saved Gemini pages and update files. See [Find your files on the SD card](/howto/sd-files/).
|
||||
|
||||
@@ -51,6 +51,22 @@ The App says why when it refuses.
|
||||
- **What can't be shown** opens as hex, with the reason: a progressive JPEG, an interlaced PNG, a BMP that is compressed or has 16 bits a pixel.
|
||||
- **A PNG needs 32 KB of memory in one piece** while it is decoded, and a few more (a JPEG needs 4 KB, a GIF 17 KB). With IRC connected there may not be that much: the viewer says so. The firmware's own screenshots need none.
|
||||
|
||||
## From a phone
|
||||
|
||||
Press <kbd>w</kbd> in the Storage App to **share the card with a browser** on the same network. The screen shows an address, as a QR code and in letters, and a six-digit code.
|
||||
|
||||
1. On the phone (or any computer on the same Wi-Fi), scan the QR code, or type the address and then the code.
|
||||
2. The page lists the card. Tap a folder to open it and a file to download it. **Upload files** sends files from the phone into the folder you are in; **New folder** and **Delete** do what they say.
|
||||
3. Press Back on the device to stop. Sharing also stops when you leave the Storage App.
|
||||
|
||||
What to know:
|
||||
|
||||
- **It runs only while that screen is open**, and the code is new each time. Five wrong codes close the door for a minute.
|
||||
- **It is not encrypted.** On your own network that is the usual trade; on a network you don't trust, someone listening could read the files and the code. Inside a VPN tunnel it is protected.
|
||||
- **One thing at a time:** while a big file is going up or down, the page waits. About 200 KB a second.
|
||||
- The same rules as on the device: the folders the firmware keeps for itself can't be deleted, and a folder has to be empty to be deleted from the page.
|
||||
- An upload is written under a temporary name and renamed when it is whole, so a transfer that is cut leaves nothing behind.
|
||||
|
||||
## Maintenance
|
||||
|
||||
At the top of the card, the last row, **Maintenance** (or <kbd>m</kbd>), shows the card's usage and holds **Storage clean-up** and **Erase SD card**. They delete for good, so they sit behind a warning. Clean-up deletes old logs and captures by category and age, showing the space it would free first. Notes and Saved Pages are never offered.
|
||||
@@ -61,4 +77,4 @@ The firmware warns once per start when the card passes **80%** full; past **90%*
|
||||
|
||||
What <kbd>Fn</kbd> + <kbd>h</kbd> shows on these screens. These tables are generated from the firmware's own lists, so they are always the current ones.
|
||||
|
||||
{{ keys(scopes=["storage", "storage-details", "storage-name", "storage-busy", "maintenance", "viewer-text", "viewer-hex", "viewer-pcap", "viewer-packet", "viewer-gpx", "viewer-ota", "viewer-image"]) }}
|
||||
{{ keys(scopes=["storage", "storage-details", "storage-name", "storage-busy", "maintenance", "viewer-text", "viewer-hex", "viewer-pcap", "viewer-packet", "viewer-gpx", "viewer-ota", "viewer-image", "storage-share"]) }}
|
||||
|
||||
Reference in New Issue
Block a user