Skip to content

Filesystem commands fail on FW2 v07 firmware: the Files menu moved under Hardware #36

Description

@bobsyourmom

Filesystem commands fail on FW2 v07 firmware: the Files menu moved under Hardware

Repo: https://github.com/freewili/freewili-python
Version: freewili 0.0.51
Environment: macOS 26.5.2 (arm64), Python 3.14.7
Hardware: FreeWili 2, firmware reports FW2 v07

Summary

Every filesystem method builds its command as x\n<cmd>, assuming Files is a
top-level menu. On FW2 v07 firmware Files has moved under Hardware, so the
correct path is h\nx\n<cmd>. As a result all of these time out against a
board that is otherwise perfectly responsive:

send_file, get_file, create_blank_file, create_directory,
change_directory, remove_directory_or_file, move_directory_or_file,
format_filesystem

fw = FreeWiliSerial("/dev/cu.usbmodemXXXXXXX", stay_open=True)
fw.open(block=True, timeout_sec=8.0)
fw.create_blank_file("test.txt")
# Err('Failed to read response frame in 6.0 seconds: ')
fw.send_file(pathlib.Path("test.txt"), "test.txt", None)
# Err('Failed to read response frame in 6.0 seconds: starting file transfer of test.txt')

Meanwhile the same connection answers fine on other commands, so this is not a
connectivity problem:

fw.get_app_info()   # Ok(FreeWiliAppInfo(processor_type=Unknown, version=7.0))

The menu layout on v07

Main menu — note there is no top-level x:

Main Menu

i) io
w) wireless
l) linux
a) apps
g) gui
s) scripting
h) hardware
r) logger

h (Hardware) then contains Files:

Hardware Functions
====================
s) Settings
a) System
x) Files          <-- here
p) Power Management
v) Display Functions
t) Get Time
c) Set Time

And hx is the menu the library already knows how to drive; the letters
are unchanged:

a) Change Directory      f) Get File From PC
c) Create Directory      u) Send File To PC
r) Remove File or Dir    p) Print File
b) Create Blank File     e) Edit File
n) Rename or Move        l) List Directory
t) Format File System    s) Toggle SDCard Host
w) Load Wili Project     k) SDCard Host Select

Confirmation at the wire level

Sending the library's command verbatim gets nothing back, while the same command
under h works:

>>> x\nf\ntest.txt 61 4155272639\n
(no response)

>>> h\nx\nf\ntest.txt 61 4155272639\n
[h\x\f ... Send File Now 1]
[h\x\f ... success 61 bytes 1]

Note on response frames when entering the submenu

Walking into Files emits an extra navigation frame with an empty body ahead of
the command's own reply:

[h\x   ... 15  1]        <- navigation, no result
[h\x\b ... 16 Ok 1]      <- the actual reply

Because _wait_for_response_frame() reads exactly one frame per command, that
navigation frame gets mistaken for the answer. Whatever form the fix takes, it
needs to account for the extra frame, not just the changed prefix. (This
compounds with the stale-frame bug filed separately, where _empty_all() fails
to clear rf_queue at all.)

Suggested fix

The menu path is firmware-dependent, so hardcoding either prefix will break the
other. Since get_app_info() already round-trips a version (7.0 here), the
prefix could be selected from it — something like a _fs_prefix property
returning "x\n" or "h\nx\n" — rather than embedding the literal in each of
the dozen or so call sites.

Worth noting for whoever picks this up: get_app_info() returns
processor_type=Unknown on this firmware, because the banner is FW2 v07 and
the regex in get_app_info only matches MainCPU|DisplayCPU|Main|Display| DEFCON25|Winky|DEFCON24. So the version is usable for this purpose but the
processor type is not.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions