toolbox: upload the Wi-Fi configuration with escsitoolbox put - #249
Merged
iTechMedic merged 2 commits intoAug 8, 2026
Conversation
Issue danifunker#87. WiFi could only be set up by pulling the MicroSD card and editing wpa_supplicant.conf elsewhere. This adds the standard SCSI Toolbox send-file commands so `scsitb put <dev> wpa_supplicant.conf` does it over the cable the drive is already on. 0xD3 names the destination, 0xD4 carries 512-byte blocks at absolute indices, and 0xD5 closes. The published protocol gives 0xD5 no payload and the DOS client declares four bytes of one, so those two lengths are accepted and no others. No new opcode and no new WiFi syntax; only WIFI.CFG and wpa_supplicant.conf are accepted, so this is not a general file upload. The SCSI path runs at IRQ level where FatFs must not be called, so blocks land in an 8 KiB buffer and ConfigService::Run writes and syncs a temporary file before rotating it into place and rebooting. Failed installs attempt to restore the working configuration; if rollback also fails, the original remains available as wpa_supplicant.bak. The buffer holds a password, so it is erased through a volatile pointer on every exit and its bytes never reach the log or the MODE SELECT parser. 25 tests drive the real gadget over the bench: the exact client transfers, fail-closed sequences, bounds and name rejection, and rollback under injected filesystem faults.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #87.
WiFi can currently only be set up by pulling the MicroSD card and editing
wpa_supplicant.confon another machine. This adds the standard SCSI Toolbox send-file commands so it can be done over the cable the drive is already on:WIFI.CFGis also accepted, for hosts limited to 8.3 filenames. Either name replaces0:/wpa_supplicant.confverbatim — no new WiFi syntax, and the existing WPA parser reads it at the next boot.Protocol
Standard opcodes only, no new vendor opcode:
0xD3names the destination,0xD4carries 512-byte blocks at absolute indices,0xD5closes.One thing worth knowing:
toolbox.hdocumentsSEND_FILE_ENDas having no payload, butToolboxSendFileEnd()in the shipping DOS client builds it as a four-byte data-out. Both lengths are accepted and nothing else is, so the released client works unmodified and a client that follows the document also works. Similarly0xD4always moves a full 512 bytes whateverCDB[1:2]says is valid, so the transfer is sized fromdCBWDataTransferLengthand only the declared bytes are copied — the padding is the client's uninitialised buffer.Scope
This is deliberately not a general shared-directory upload. Only the two Wi-Fi configuration names are accepted; empty names, names with no terminator inside the parameter list, control bytes, path separators, drive prefixes and dot traversal are all refused with ILLEGAL REQUEST before anything is staged.
D0,D2,D7,D8,D9andDAare unchanged.Safety
The SCSI path runs at IRQ level where FatFs must not be called, so blocks land in a fixed 8 KiB staging buffer and
ConfigService::Rundoes the disk work — the same split that already exists because its setters are called from interrupts andSave()happens in its loop.SCSITBServiceis not involved.Nothing touches the card until
D5has returned GOOD. The install then writes a temporary file, checks the byte count (a full card isFR_OKwith a short write, not an error return), syncs, and rotatesconf→.bak→conf, since FAT cannot replace atomically. Any failure — short write, bad sync, failed rename, abandoned transfer, USB reset — leaves the working configuration alone and does not reboot. If an install fails and the rollback rename also fails, the old configuration still exists under.bak; that case is logged by name, and the next attempt will not clear a backup that has no working file beside it.The staging buffer holds a WiFi password, so it is erased through a
volatilepointer on every exit path, and the data-out payload is routed by opcode rather than falling through toProcessOut()'s MODE SELECT parser — whose debug dump would otherwise print the first 24 bytes of a PSK.The reboot that applies the new configuration is scheduled only after the commit succeeds, and 3 s later, so the CSW reaches the host first.
Tests
25 new tests in
integration-tests/test-suite/test_toolbox.cppdrive the real gadget over the bench: the DOS client's exact 33/512/4 transfers, the documented no-payload END, absolute placement and retries, partial final blocks, every fail-closed sequence, oversized and gapped uploads, rejected names and traversal attempts, short and oversized data phases, short-write / sync-failure / rename-failure faults with their rollbacks, and that no password reaches the log or the volume control. The existing toolbox tests are unchanged.The FatFs host seam gains
f_unlinkandf_rename, a rename fault injector, and a drive-root mapping so0:/...paths resolve into a scratch directory.make -C integration-testsWITH_CHD=1Also built clean as a 64-bit Raspberry Pi 3 package.
Open questions
WIFI.CFGandwpa_supplicant.confboth writewpa_supplicant.conf. IfWIFI.CFGwas meant to be a distinct simplified format, that would be a separate change.