🦊 Fox ESP32 Firmware

Complete User Guide

Fox ESP32 Firmware turns a cheap ESP32 dev board into a WiFi/Bluetooth companion for your Flipper Zero β€” recon, gated attacks, item-tracker detection, a Discord bridge, a lead-capture captive portal, an embedded scripting layer, and an internet bridge that speaks real FlipperHTTP (jblanked/FlipperHTTP) for its core commands, all talked to over a simple wired UART connection.

πŸ”§ New here? Start at Hardware Setup to wire your ESP32, then Web Installer to flash it.
Chapter 1

About Fox ESP32 Firmware

Fox ESP32 Firmware is a single Arduino sketch that runs on a cheap ESP32 dev board and talks to your Flipper Zero over a plain wired UART connection (no BLE pairing, no WiFi bridge between the two devices β€” just four wires). Your Flipper sends it plain-text commands one line at a time; the ESP32 does the actual WiFi/Bluetooth/internet work and reports back. A suite of companion Flipper Zero apps gives you a menu-driven interface to the firmware so you never have to type raw commands by hand β€” though you always can, via the Terminal.

For authorized security testing and research only. WiFi/BLE reconnaissance and attack commands are gated behind a single Attacks toggle (on by default, matching how most similar tools ship) β€” see Safety, Legal & the Attacks Toggle. Know your local regulations before transmitting anything.

The eight pieces of the project:

Fox ESP32 Firmware
Runs on the ESP32
The actual WiFi/BLE/HTTP/Discord/scripting engine. One firmware image, flashed once.
Fox ESP32 Detector
Flipper app
Diagnostic tool β€” tells you which GPIO pins and baud rate your ESP32 is actually wired/talking on.
FoxHub
Flipper app
The main control app β€” WiFi, Bluetooth, Tag Detection, Scripts, Settings, Terminal.
Fox Chat
Flipper app
Post to and read from a Discord channel through the ESP32's internet connection.
Fox Portal
Flipper app
A configurable, consent-based lead-capture WiFi captive portal with QR join and auto-detected field logging.
Fox ESP32 Flasher
Flipper app
Flash Fox ESP32 Firmware onto a connected board directly from the Flipper β€” no PC required.
Fox ESP32 Terminal
Flipper app
A focused live-terminal companion β€” streaming console, quick command send, and per-session SD-card logs.
Fox Update Downloader
Flipper app
Checks GitHub for newer FoxFW2.0 and Fox ESP32 Firmware releases, downloads them over the ESP32 bridge, and hands off to install β€” see Chapter 9.

What you can do with it:

Chapter 2

Web Installer

The ESP32 side of this project is flashed from your browser β€” no Arduino IDE, no esptool command line, nothing to install. You only need a USB cable and a Chrome- or Edge-based desktop browser (Web Serial support is required; Safari and Firefox cannot do this).

⚑ Open ESP32 Web Flasher β†’

Hosted alongside the Flipper firmware flasher on the FoxFW GitHub Pages site.

Keep the browser tab in focus while flashing. The Web Serial connection and the flash transfer both run in that tab β€” switching away, closing the laptop lid, or letting the system sleep mid-flash can interrupt the transfer.

Choosing your board

You don't have to. The Model dropdown starts on Auto-detect on connect: when you click Connect, the flasher asks the chip what it is and loads the matching Fox firmware for you. Leave it on auto unless you have a reason not to.

Model entryChipBootloader address
ESP32-S2 β€” Flipper Wi-Fi Dev Board (official)ESP32-S20x1000
ESP32 (original) β€” WROOM / WROVER / ESP32-CAMESP320x1000
ESP32-S3ESP32-S30x0
ESP32-C3ESP32-C30x0
ESP32-C5ESP32-C50x2000
ESP32-C6ESP32-C60x0

Every board flashes the same four files β€” Bootloader, Partitions, Boot App0, and Firmware β€” at the same addresses except for the bootloader itself, whose address differs by chip family. The flasher fills these in for you.

The official Flipper Wi-Fi Dev Board is an ESP32-S2, not an "ESP32 Dev Module". It has no USB-to-serial chip, so it has to be put in bootloader mode by hand before the browser can see it: hold BOOT, tap RESET, release BOOT, then click Connect.

Step by step

  1. Open the Web Flasher link above in Chrome or Edge on desktop.
  2. Plug your ESP32 into your computer with a USB data cable. Flipper Wi-Fi Dev Board: hold BOOT, tap RESET, release BOOT.
  3. Click Connect and pick your device from the browser's own serial port picker.
  4. The flasher identifies the chip, selects the matching board and downloads the Fox firmware for it. The hint under the Connect button tells you when it's ready.
  5. Click Program. A progress bar tracks each of the four files as they're written, and each one is read back and verified.
  6. When it finishes, the board restarts into the new firmware and the flasher disconnects. If the board doesn't come up, press RESET once or unplug and replug it.

To flash your own build instead, switch to the Select Custom Firmware Files tab and choose each of the four files (the ones Arduino IDE's Sketch β†’ Export Compiled Binary produces, see Hardware Setup).

Wrong-board protection

The chip that answers on the port always decides which firmware is used. If you picked a model by hand and it doesn't match the connected chip, the flasher switches to the right one and says so in the console; while a board is connected it won't let you switch to another chip's firmware. Custom files are checked too: an image built for a different chip is refused before anything is written, because it would leave the board unable to start.

Erasing the flash

The Erase button wipes the entire flash chip. You'll get a confirmation prompt first. This is useful if a previous flash left the board in a bad state, or before switching a board between firmware projects.

Statistics

At the bottom of the Web Flasher there is a Statistics bar. Click it to see how many installs have finished, by month, day, country, chip, firmware version, connection type, operating system and browser, and where failed attempts stopped. Use < and > to move between months. The same panel is on the FoxFW Web Installer and the FAP Compiler, where it also lists the most compiled and most recently compiled apps.

The numbers are public and anonymous: each install adds one to a counter. No IP addresses, cookies, device IDs or personal details are stored.

Flashing via Flipper Zero (no PC required)

If you already have FoxFW installed on your Flipper, you can flash the ESP32 directly from the device β€” no browser, no USB cable to a computer, no files to download. The firmware for every supported board is bundled into FoxFW and deployed to your SD card automatically during the standard qFlipper install.

  1. Connect your ESP32 to the Flipper Zero GPIO header: TX (GPIO1) β†’ Pin 14, RX (GPIO3) β†’ Pin 13, GND β†’ GND, 3.3V β†’ 3.3V.
  2. On your Flipper go to Apps β†’ Fox β†’ Fox ESP32 Flasher.
  3. The app detects your connected ESP32 automatically. If nothing is found, check your wiring and try again.
  4. Select Flash Firmware, then choose your board type from the list.
  5. Confirm the firmware files shown and press Flash. The app writes the bootloader, partition table, and firmware in a single pass and shows a progress bar.
  6. Press Done when complete β€” the ESP32 resets automatically.
Recommended for re-flashing in the field. Once FoxFW is on your Flipper, the Fox ESP32 Flasher is the fastest way to update or recover an ESP32 without needing a computer nearby.
Chapter 3

Hardware Setup

Wiring the UART link

The Flipper and the ESP32 talk over a plain 4-wire UART connection β€” no special adapter needed, just jumper wires from the Flipper's GPIO header to the ESP32's RX/TX/GND/5V (or 3V3) pins. Every Flipper-side app in this project (Detector, FoxHub, Fox Chat, Fox Portal) probes the same two standard pin pairs automatically at boot, so as long as you wire into one of these two pairs, every app will find your ESP32 without any manual configuration:

PairFlipper GPIO pinsInternal name
Pair 113 / 14USART
Pair 215 / 16LPUART

All communication runs at a fixed 115200 baud.

Don't know which pins you used, or whether your wiring even works? That's exactly what Fox ESP32 Detector is for β€” it tests both pairs automatically and tells you which one is live.

Board differences

Fox ESP32 Firmware supports the classic ESP32 and its variants, with real differences in what each one can do:

ESP32 (Classic) / ESP32-S3
Full support β€” WiFi, raw 802.11 frame injection (needed for deauth/beacon-spam/etc.), and Bluetooth LE all work. These are the two boards with ready-made Web Installer entries today.
ESP32-C3 / C6
Expected to work unmodified β€” same Arduino APIs, just compiled for the RISC-V toolchain arduino-esp32 provides for these chips. No ready-made Web Installer entry yet; compile and flash manually.
ESP32-C5
Needs a recent-enough arduino-esp32 core. Raw-injection support for attack commands hasn't been independently confirmed on this chip.
ESP32-S2 No BLE
This chip has no Bluetooth radio at all β€” a hardware limitation, not a firmware choice. WiFi, HTTP, and FoxScript all work normally. Every Bluetooth-related command (the BLE bridge, BLE spam, Tag Detection) replies with a plain error instead of failing silently, so it's always obvious when you're on an S2 board.
Applies to: the Bluetooth menu and Tag Detection menu in FoxHub

Optional add-on hardware

Four extra hardware peripherals can be wired to the ESP32 for expanded functionality. Each one is a separate breakout board you add yourself β€” none of them ship as part of the base kit β€” and each is controlled by its own build-time flag in the firmware, off by default. If you want one of these, you (or whoever builds your firmware image) needs to turn the flag on and recompile; it can't be toggled at runtime like the Attacks setting can.

PeripheralChip / interfaceWiringWhat it adds
RFID PN532 breakout, I2C IRQ β†’ GPIO 25, Reset β†’ GPIO 26 (SDA/SCL use the ESP32's default I2C pins) Mifare Classic scan / read / write
Sub-GHz CC1101 breakout, SPI SCK β†’ 18, MISO β†’ 19, MOSI β†’ 23, CS β†’ 27, GDO0 β†’ 32 Raw sub-GHz RX/TX (300–928 MHz) β€” no protocol decoding, raw capture/replay only
IR IR LED + demodulating receiver Send β†’ GPIO 4, Receive β†’ GPIO 5 Send/receive/decode across dozens of IR protocols, plus a small TV-power-toggle sweep
GPS Any NMEA 0183 GPS breakout (e.g. NEO-6M/8M) RX β†’ GPIO 16, TX β†’ GPIO 17, 9600 baud (UART2) Live fix/position/track data, POI marking, and GPS-tagged WiFi wardriving

With a peripheral's flag left off, every command for that hardware replies with a specific error (ERROR:NORFID, ERROR:NOSUBGHZ, ERROR:NOIR, ERROR:NOGPS) rather than doing nothing silently, so it's always clear whether a missing feature is "not wired up" versus "not working."

Chapter 4

Fox ESP32 Detector

A single-purpose diagnostic app: it tells you whether anything is actually talking on your Flipper's GPIO header, and if so, which pins, which baud rate, and β€” where it can tell β€” which firmware. There's no menu, no configuration, and nothing is saved. Point it at a freshly wired board when you're not sure the wiring is right, or when Fox ESP32 FoxHub reports "not detected" and you want to know why.

How it works

Press Scan and watch a live progress bar work through every combination of the two Flipper pin pairs and nine common baud rates β€” 18 combinations total. For each one, it tries up to four detection tiers in order, stopping at the first one that answers:

Tier 1Listen for GPS
(NMEA sentences, no command sent)
β†’
Tier 2Send AT
ESP-AT firmware check
β†’
Tier 3Send info
Known non-AT firmware (Bruce, Fox ESP32 Firmware)
β†’
Tier 4Send ?
Generic fallback, requires a repeatable response

Baud rates tested: 9600, 19200, 38400, 57600, 74880, 115200, 230400, 460800, 921600. A full scan of a board with nothing connected takes roughly 30 seconds, since every combination has to time out before moving on.

What it can identify today: Fox ESP32 Firmware itself (matches this project's own self-identification string), and Bruce firmware (a different, unrelated ESP32 project) as a bonus. Marauder doesn't have a safe self-identify command, so a Marauder-flashed board will show up as "Unidentified" rather than being named.
Scope note β€” what this tool does not detect: a raw, unflashed ESP32 chip's bootloader (that needs two additional wires and a different protocol entirely), I2C/SPI sensor breakouts, or anything that doesn't speak line-based serial commands. This is purely a "does something on this GPIO pair understand my Flipper's serial protocol" check.
Chapter 5

FoxHub

The main control app for the firmware β€” WiFi, Bluetooth, item-tracker detection, automation scripts, the safety toggle, and a raw Terminal, all in one menu tree. This is the app you'll spend the most time in.

First run & detection

Opening the app always follows the same sequence:

1. SplashFox logo, ~2s
β†’
2. DetectProbes both pin pairs for the firmware's self-ID
β†’
3a. FoundStraight to the main menu
β†’
3b. Not foundRetry screen

If nothing answers on either pin pair, you'll see a short message β€” "Fox ESP32 Firmware required on ESP32 connected via GPIO." β€” with two options: Retry (probes both pin pairs again, useful if you just plugged something in) and Settings (opens Connect Settings, below).

Connect Settings
Reached only from the Retry screen's Settings button. An arrow-adjust screen with a Pins row (13/14 or 15/16) and a Baud row (115200 only today β€” the row is built to support more rates later). A Retry row re-probes using exactly the pair you've selected, rather than trying both. Use this if you know exactly which pins you wired and want to skip the automatic dual-pair probe.
Not detecting at all? Run Fox ESP32 Detector first to confirm your wiring and baud rate independently of this app.
Global default New: Fox Settings now has its own ESP32 UART toggle (13/14 or 15/16) that's shared across FoxHub, Terminal, Flasher, and the built-in UART Terminal. Changing the pin pair from any one of those apps' own Connect Settings updates this same shared default β€” so once you've told one app which pins you wired, the others start from that choice too instead of always defaulting back to 13/14.

Main menu:

WiFi menu

Connect / Connection

The network list merges a live scan with your saved networks (saved ones shown first), as rounded Fox-styled rows showing SSID, signal strength, security type, and whether it's saved. Selecting a saved network reconnects immediately. Selecting a new one prompts for a password (leave blank for open networks) and saves it for next time. Once connected, the same menu item relabels itself Connection and opens a submenu instead: Disconnect, Status (current SSID + IP), Connect to Network (switch to a different saved/new network), and Forget Network (removes the saved password and disconnects).

This is the menu that drives your Flipper's own status bar WiFi icon. Every Connect/Disconnect/Forget/Status action here updates a small status file on your SD card that the Flipper's desktop polls β€” see Status Bar WiFi / CC1101 Icon. Fox Chat and Fox Portal don't touch this file β€” they just use whatever WiFi connection is already active.

My IP & HTTP Request

My IP fetches your ESP32's public internet-facing IP address and prints it to Terminal. HTTP Request gives you a quick GET (just a URL prompt) or POST (URL, then a body prompt) without needing to type bracket-command syntax yourself β€” the raw response is shown in Terminal either way. This is deliberately just GET/POST with no custom headers or other verbs; Terminal is there for anything more advanced (see the full HTTP command reference).

Recon

Scan APs and Scan Stations populate the network/station lists used elsewhere in this menu. Signal Monitor and Packet Count are quick, bounded checks (10 and 5 seconds respectively) that stream straight to Terminal. Wardrive and Packet Capture are the two data-logging tools:

Wardrive
Scans nearby access points and tags each one with your current GPS fix (requires the GPS peripheral, see Hardware Setup). Appends to a dated CSV on your SD card, one file per day.
File: /ext/apps_data/fox_esp32/wardrive/wardrive_<YYYY-MM-DD>.csv
Columns: bssid, ssid, latitude, longitude, rssi, channel, encryption_type, timestamp
Packet Capture
Captures raw 802.11 frames for 15 seconds, hopping channels 1–11 every 400ms, and saves a real, standard .pcap file β€” opens directly in Wireshark, no conversion needed.
File: /ext/apps_data/fox_esp32/captures/capture_<timestamp>.pcap

Attacks Gated

Every item in this submenu requires Attacks to be turned on in Settings β€” with it off, every action here replies with a plain "disabled" message instead of doing anything. All attack primitives run for a fixed 5-second burst and then stop on their own; no separate stop button exists because none is needed.

Select AP / Select Station first. Deauth and several other attacks act on whichever AP/station you last selected via Recon's scan screens β€” if you haven't picked one, targeted actions will tell you so rather than doing nothing silently.

Bluetooth menu

This menu is BLE spam only β€” five gated items, each cycling a proximity-pairing-shaped advertisement for 8 seconds to trigger the matching OS's pairing popup nearby.

Not available on ESP32-S2 boards (no BLE radio). This menu is unrelated to the general-purpose BLE bridge command set (BLEINIT, BLESCAN, BLECONN, etc.) built into the firmware for talking to other BLE devices β€” those commands are reachable from Terminal but don't have a dedicated menu screen in this app.

Tag Detection menu

Each item runs a bounded 8-second BLE scan for that tracker family's broadcast signature and prints any matches straight to Terminal β€” mac address, signal strength, and (for Find My only) a decoded battery hint. This is not gated by the Attacks toggle β€” detecting nearby trackers is passive listening, not an attack.

This is a snapshot, not a stalking detector. A match means "a tag matching this family's broadcast format is nearby right now" β€” it does not mean the tag has been following you, and repeated scans over time aren't tracked or correlated. AirTag/Find My detection matches Apple's shared "offline finding" broadcast format, which every Find My accessory uses (not just AirTags specifically) β€” the protocol itself can't distinguish which exact product sent it.

Scripts menu

Lists every script currently saved on the ESP32, plus a trailing New Script item. Selecting an existing script opens Run / Show / Delete (deliberately not run-on-select, so Delete is never one accidental press away). New Script prompts for a name, then the script's source code, and saves it.

Typing long scripts on-device is slow. For anything more than a few lines, write your script as a single line and send it via Terminal using the raw SCRIPTSAVE: command instead β€” see FoxScript for the full language reference.

Settings & Terminal

Settings β€” Attacks: ON/OFF, Expert Mode: ON/OFF
Two arrow-adjustable rows. Left/Right on the highlighted row toggles it; a small < > pair appears inside the box to remind you which direction to press. Changes apply immediately over serial β€” there's no separate save step. Attacks adds WiFi/BLE attacks to the relevant menus when turned on. Expert Mode adds a Terminal Command item to the main menu for sending a single raw command without opening the full Terminal. This screen always queries the firmware's real, persisted value when you open it, so it never drifts out of sync with what the ESP32 actually has stored. This is different from Connect Settings (pin/baud override), which only appears from the not-detected Retry screen.
Terminal
Raw command access to the firmware, and also where most menu actions log their results β€” a single running transcript of everything that's happened. Type any command from the full command reference directly here.
Chapter 6

Fox Chat

Post to and read from a Discord text channel, straight from your Flipper's screen, using your ESP32's internet connection. You'll need an active WiFi connection (set up via FoxHub's WiFi menu) β€” nothing else to configure.

Post Message
Prompts for your message text, then sends it prefixed with your Flipper's own device name β€” e.g. MyFlipper: hello β€” so anyone reading the channel can tell which device posted it. If the message is blocked by the content filter you'll see "Blocked - message flagged by content filter"; if you're posting too quickly you'll see "Too soon - wait a few seconds and try again."
Read Messages
Fetches the most recent messages and shows them as a scrollable list of two-line buttons β€” select one to see the full text and when it was sent. Wherever a message has that DeviceName: prefix (i.e. anything posted through Fox Chat, from any Flipper), the device name renders in bold with the rest of the message following normally. The ESP32 probes an IP-geolocation service for your local UTC offset the first time it connects to WiFi, then converts every message's timestamp to that local time automatically β€” no setup needed. The date is only shown alongside the time if the message wasn't sent today; if the ESP32 hasn't been able to determine your timezone yet, times fall back to plain UTC (labelled accordingly).
No setup, no bot to create. Every FoxFW device posts to and reads from the same shared FoxFW community Discord channel by default. The real Discord bot token lives only in a small relay server FoxFW runs β€” it never touches your Flipper or ESP32, and there's no token or channel ID to enter anywhere.

Content moderation β€” what's protected and what isn't

Chapter 7

Fox AI Chat

Chat with Google Gemini directly from your Flipper's screen, using your ESP32's WiFi connection. You'll need an active WiFi connection (set up via FoxHub's WiFi menu) β€” nothing else to configure, no API key to enter.

Post Message to AI
Opens the keyboard for your message. If you've messaged within the last 60 seconds, you'll see a Message Limit screen instead β€” a progress bar counting up to the 60-second mark, with a Back button below it. It jumps straight to the keyboard the instant the cooldown clears. Once sent, a progress screen walks through Sending Message... then Receiving Reply... before dropping you into the chat log with your exchange at the bottom.
Read AI Chat
Shows the full conversation in a scrolling terminal view, titled "AI CHAT", scrolled to the most recent messages. Everything you've ever sent and every reply is saved permanently to chat.ai on the SD card β€” your messages appear as <YourFlipperName>: <message>, replies as FOX-AI: <reply>.
Clear Chat
Deletes chat.ai and starts a fresh one, stamped with the date and time it was created. This is the third menu item β€” since only two show on screen at once, scroll down to reach it.
No API key, no setup. Every FoxFW device talks to the same shared Gemini relay FoxFW runs, the same pattern Fox Chat uses for Discord β€” the real Gemini API key lives only on that relay server, never on your ESP32 or Flipper. A 60-second cooldown between messages is enforced both on the ESP32 and, as a backstop, on the relay itself, to keep the shared quota available for everyone.
Chapter 8

Fox Portal

Stands up an open WiFi network with a small enquiry-form landing page β€” anyone who joins sees your page, fills it in, and gets a confirmation screen, with every submission logged to a text file. Unlike a typical "evil portal," this one is built for consent-based lead capture: the visitor is knowingly opting in and the confirmation page shows them exactly what was recorded, not a credential phishing trap.

Start / Stop
The menu only ever shows the one that applies β€” Start when the portal is off, Stop once it's running β€” swapping automatically as soon as the ESP32 confirms the change. Start prompts for an SSID, pre-filled with whichever one you used last (or the built-in default, "Fox Portal Demo", the very first time) and pre-selected β€” press Save to reuse it as-is, or just start typing to replace it. Before starting, it re-reads your page files fresh from the SD card every single time, so any edits you've made β€” from the app itself or by hand on a computer β€” are always picked up. The portal then goes live as an open WiFi network with a captive-portal redirect: joining devices are automatically redirected to the enquiry-form page rather than just showing "no internet access." Stop shuts down the WiFi network and web server.
View Saved Results
Shows everything captured so far, straight from portal.txt on your SD card. You don't need to select this to actually get your results onto the Flipper β€” see "Submission logging" below for how that happens automatically. This screen just displays what's already there (scroll with Up/Down; if the file has grown large, only the most recent portion is shown on-screen, with a note at the top β€” the full history always remains in the file itself).
Show QR
Displays a scannable WiFi-join QR code for the currently active portal SSID, so visitors can join with a camera scan instead of typing a network name. The portal network is always open (no password).

Customizing the pages β€” start.html, finish.html, portal.cfg

These three plain files live on your Flipper's own SD card and are the real source of truth for what visitors see β€” nothing here is compiled into the ESP32 firmware, so editing them never requires a reflash.

FilePathWhat it controls
start.html/ext/apps_data/fox_portal/The enquiry-form page visitors see first
finish.htmlThe confirmation page after submitting
portal.cfgJust one line: the last-used (or default) SSID, pre-filled into the Start prompt next time

Open and edit these directly β€” via qFlipper's file browser, the Flipper Mobile App, or by pulling the SD card into a computer. Add or rename fields in start.html by editing its <input name="<fieldname>"> tags directly β€” whatever names actually get submitted are auto-detected and logged, so there's no separate field list to keep in sync. In finish.html, use {{FIELD:<fieldname>}} anywhere you want to echo back what the visitor submitted for that field.

Starter templates are included automatically. A ready-made example set β€” a plain "Get In Touch" page with name and phone fields, styled with a dark background and orange accent β€” is bundled into the firmware and deployed to /ext/apps_data/fox_portal/ on your SD card during the standard qFlipper install. No manual copying required. Edit the files from there to customise your portal. The first time Fox Portal runs, portal.cfg is created the same way if it isn't already there, seeded with the built-in default SSID ("Fox Portal Demo").

Each HTML file has a 1024-byte size limit once flattened to a single line (a transfer-safety limit, not an HTML restriction) β€” the included starter templates use under 1000 bytes each, leaving room to adjust copy or light styling.

Submission logging

Every submission is appended as its own self-describing line β€” SSID=...;fieldname=value;fieldname=value... β€” to a text file on the ESP32 named for that portal session's start time, so each time you run Start gets a fresh file. Whatever fields a visitor's page actually submits are the fields that get logged for that line; there's no fixed column list, so different sessions can collect different fields without anything lining up wrong.

Those session log files only ever live on the ESP32 temporarily. Loading the Fox Portal app immediately triggers a transfer of anything waiting there into portal.txt on your Flipper's SD card (/ext/apps_data/fox_portal/portal.txt), clearing it from the ESP32 to free that flash up for new submissions. From then on, while you stay on Fox Portal's menu, it automatically checks again every 5 seconds and pulls over anything new β€” you don't need to back out and re-open the app, or select View Saved Results, for a submission to make it across; leave the menu open and it shows up within a few seconds. Nothing queued just means a quiet no-op. Use View Saved Results to read back what's accumulated in portal.txt so far.

This hand-off is verified before anything is deleted. Every row the ESP32 sends is numbered and counted (LOGLINE:<seq>:..., cross-checked against LOGFILE:/LOGFILEEND:/LOGDONE: totals). The Flipper stages the data on its SD card and checks every number lines up before writing it into portal.txt - and only after that write succeeds does it send WIFIFOXPORTAL:EXPORTCONFIRM, which is the one and only thing that tells the ESP32 it can delete its copy. If anything drops or doesn't add up along the way, nothing is written and nothing is deleted - the same data just gets resent automatically on the next sync, whether that's opening the menu or the 5-second auto-check. The only edge case that can still happen is a duplicate row already safely on your SD card, if the very last confirmation step itself doesn't get through - never a row that disappears without a trace. If that ever happens, Fox Portal's action log says so explicitly rather than staying quiet about it.
Very long rows are marked, not mangled. If a row (SSID plus every configured field's value) would run longer than a single reply can safely carry, the ESP32 shortens just that row and appends ...[TRUNCATED-TOO-LONG] before sending it - the row still exports and still counts normally, so it never breaks the verification above. You'd only ever see this with several fields set to unusually long values; if you spot it in portal.txt, that submission's later fields were cut off and it's worth trimming your field lengths going forward.
Chapter 9

Fox Update Downloader

Checks GitHub for newer releases of both FoxFW and Fox ESP32 Firmware, downloads whichever one you pick, and hands off straight to install β€” no PC, no browser, no manual file copying. Because the Flipper itself has no internet connection of its own, this app reaches GitHub over your already-wired ESP32 the same way FoxHub does β€” it needs the same UART wiring and a WiFi network for the ESP32 to join.

Checking for an update

Pick a row and the app connects to your ESP32, asks it to fetch the latest release from GitHub, and shows a progress screen while it compares versions. You'll land on one of three outcomes:

Up to date
Your installed version already matches the latest release. Press OK to return to the menu.
Update available
Shows the current version alongside the new one. Not now backs out without downloading anything; Download starts the transfer.
Check failed
No WiFi connection, no ESP32 detected, or GitHub couldn't be reached. Press OK and try again once the underlying issue is sorted β€” Fox ESP32 Detector can help confirm your wiring is the problem or not.

Selecting your ESP32 board

Choosing Fox ESP32 Firmware adds one extra screen before the check begins: Select Board. Use Left/Right to cycle through the six supported targets β€” ESP32 Classic, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C5, ESP32-C6 β€” then Down and OK on Continue. This tells the app which three files to fetch (bootloader, partition table, and firmware image are downloaded separately for this flow) and which board profile to hand to the flasher afterwards.

Pick the board that matches your actual chip. Same rule as the Web Flasher's chip-mismatch protection β€” flashing the wrong board's image won't boot. If you're not sure which chip you have, check the silkscreen on your dev board or the listing you bought it from.

Downloading

A progress screen shows the file currently being fetched by name, a percentage, and a running KB / KB total β€” for the ESP32 flow this cycles through all three files in turn (bootloader β†’ partition table β†’ firmware) under one combined progress bar. Press Back at any point to cancel; anything already written to your SD card is cleaned up automatically rather than left as a partial, unusable file.

Stalled or interrupted transfers retry automatically β€” up to three attempts per file before giving up and reporting a failure, so a brief WiFi hiccup mid-download usually resolves itself without you needing to do anything.

Installing

Once the download finishes you'll see Downloaded with two options: Install hands off immediately, or Later keeps the file on your SD card and returns you to the menu without installing. Choosing Later shows a Not Installed screen with Menu (just go back) and Restart (install the already-downloaded copy right now) β€” so you never have to download the same release twice just because you weren't ready to install the first time.

Installing Fox Custom Firmware
Hands off to the Flipper's own built-in firmware updater β€” the device restarts automatically to apply it, exactly like installing a .fuf from the Fox File Browser. See the FoxFW guide's Installing Firmware Updates chapter for what happens next (the Fox Setup Wizard runs once on first boot).
Installing Fox ESP32 Firmware
Hands off to Fox ESP32 Flasher with the board and downloaded files already selected β€” it writes the bootloader, partition table, and firmware in one pass with its own progress bar, then resets the ESP32 automatically. You don't need to re-pick the board or the files yourself.
Chapter 10

Fox File Downloader

Downloads files onto your SD card over the ESP32's internet connection β€” a direct URL, a browsable App Catalog, or a .fap straight off a GitHub repo β€” plus its own WiFi menu for connecting, scanning, and (if Attacks is on) the same recon/attack tools as FoxHub.

File Download (URL)

Prompts for a single URL β€” there's no separate filename prompt. The filename is worked out automatically from the last segment of the URL; if a file with that name already exists it's saved as name (2).ext, name (3).ext, and so on rather than overwriting anything. Files land at /ext/downloads/. The field remembers the last URL you entered (pre-filled next time), or starts at http:// the very first time.

Opening this menu item doesn't necessarily show that keyboard right away β€” it checks two things first, in order:

1. An interrupted download
If a previous download didn't finish, you'll see Download Interrupted with the filename and two buttons: Resume (continues from where it left off, straight into the normal downloading screen) and Restart (deletes the partial file and downloads from byte 0 again). Resume works via a real HTTP Range request β€” the ESP32 asks the server for only the remaining bytes, rather than re-downloading what you already have.
2. A queued URL β€” see Download.txt below
If neither of those apply, you get the URL keyboard as normal.

Once a URL is confirmed, the flow is a single continuous connection:

ConnectingBar fills against a 28s timeout, not real progress
β†’
ConnectedShows size (or "size unknown") + Cancel/Download
β†’
DownloadingFilename, bar, % and speed (or bytes if size unknown)
β†’
CompleteFull bar, save location + filename
Redirects and HTTPS are both handled automatically — up to 5 redirect hops are followed even across an http→https upgrade (common on hosts that force one), and HTTPS downloads work without any extra setup.
"Stream protocol error"? This is a UART framing hiccup, more likely at higher baud rates. The Terminal log tells you exactly what to do about it β€” drop to 115200 Baud in Download Settings if you're above it, or reset the ESP32 if you're already there.

Download.txt queue

A plain text file at /ext/download.txt (SD card root, not in apps_data) β€” created automatically the first time you open the app if it doesn't already exist, with a header comment explaining itself. One URL per line; blank lines and lines starting with # are ignored. Opening File Download (URL) checks this file for the first non-comment line and downloads it automatically, no keyboard shown β€” once it starts, that line gets a # inserted in front of it so it's not picked up again, but it stays in the file as a record rather than being deleted. Only one URL is taken per visit, so queue up as many as you like and reopen File Download (URL) to work through them one at a time.

App Catalog

Browses catalog.flipperzero.one by category β€” Bluetooth, Games, GPIO, Infrared, iButton, Media, NFC, RFID, Sub-GHz, Tools, USB β€” showing one app at a time with its description, version, and position in the list. Left/Right moves between apps (and pages, once you reach either end); OK installs the highlighted app straight to /ext/apps/<Category>/, matching the category folder Flipper itself expects.

Firmware API is 88.2, most catalog apps are still 87.x β€” installs may fail for now. Shown once per app session the first time you open App Catalog. The catalog only offers a build if one exists that's compatible with your exact firmware API version and hardware target; if it doesn't, you'll see "App's catalog build doesn't match this firmware's API. May work on other firmware." instead of a download.

GitHub Repos

Type a repo as owner/repo (not a full URL) β€” e.g. jblanked/FlipDownloader. The app fetches the repo's default branch and scans its entire file tree for anything ending in .fap, wherever it lives in the repo (this looks at the raw tree, not GitHub Releases or a build workflow β€” the app needs to already contain a built .fap file checked into the branch). Pick one from the list and it downloads straight from raw.githubusercontent.com to /ext/apps/GitHub/<filename>.

If GitHub's response for a very large repo gets truncated, the header shows (partial) next to the repo name β€” the list you see may not be every .fap in the repo.

Manage Apps

Lists every .fap under /ext/apps (skipping any folder literally named assets, so bundled app resources aren't shown or touched) as a path relative to that folder, e.g. Tools/myapp.fap. Selecting one shows a confirm screen β€” OK deletes it, Back cancels β€” and the list refreshes afterward.

Download Settings

The main menu's Settings item goes straight here β€” this app doesn't have a separate Connect Settings screen reachable from the menu the way FoxHub does. Four rows, Left/Right to cycle, saved automatically on every change:

Baud
UART speed used during an active download stream (separate from the fixed 115200 used for detection). 115200 / 230400 / 460800 / 921600 β€” higher is faster but more prone to the "Stream protocol error" desync.
Default: 115200
Retries
Max connect/stream attempts per download before giving up, shown as "Try N/M" on the progress screen.
Default: 3 β€” choices: 1, 2, 3, 5, 10, 15, 20
Timeout
Per-chunk idle timeout in seconds β€” if no data arrives for this long mid-download, that attempt is treated as failed and retried.
Default: 10s β€” choices: 5, 8, 10, 15, 20, 30, 45, 60
Auto Lower Baud
When on, if the configured baud is above 115200 and a download keeps failing, the app temporarily steps the baud down a notch to retry, then keeps whatever baud actually worked.
Default: No

WiFi, Recon & Attacks

Same shared WiFi module as FoxHub β€” full network connect/manage plus Recon and (if enabled) Attacks, not a trimmed-down "just connect" menu. The main menu's WiFi item disappears once you're connected, replaced by nothing (there's no menu-level shortcut to the Connection submenu here the way FoxHub has one) β€” reopen WiFi from Terminal/Settings context if you need to check status without disconnecting.

Every screen, file format, and gated-behind-Attacks rule here is identical to FoxHub's WiFi menu β€” see Chapter 5's WiFi menu for the full breakdown (Wardrive's CSV columns, Packet Capture's .pcap format, saved-network handling, and so on). Attacks is turned on and off from FoxHub's Settings screen β€” it's one shared toggle stored on the ESP32 itself, not per-app.
Chapter 11

FoxDeFlock

A Flock Safety / ALPR (automatic license plate reader) camera detector, using your ESP32 as the WiFi/BLE radio. Based on FlipDeFlock by ReconGrunt (GPL-3.0-or-later) β€” this port reuses FlipDeFlock's OUI/SSID confidence-scoring and BLE-advert decoding logic verbatim, rebuilt against Fox ESP32 Firmware's own command set instead of FlipDeFlock's Marauder-based backend.

Setup

Requires Fox ESP32 Firmware wired via UART at 115200 baud (standard Fox pinout). On launch the app checks for an ESP32; if it isn't found, you get an ESP32 not found screen with Settings (pick which UART pin pair to use β€” 13/14 or 15/16) and Retry buttons. Nothing destructive happens if no ESP32 is present β€” the app just never sees any hits.

Scanning

Once connected, FoxDeFlock rotates through three scan modes every ~8.5 seconds, shown in the top-right corner of the hit list:

ModeWhat it scans
WiFi:ProbeWiFi probe requests
WiFi:BeaconWiFi beacon frames
BLE:FlockFlock external-battery BLE adverts (BLETAGSCAN:FLOCK)

Each hit is shown as a single row: source (WiFi/BLE), the last two MAC bytes, an SSID or BLE name if one was broadcast, and a confidence code (CONF/FP?/LIKE/POSS). Up and Down move the selection; OK on a hit opens its detail screen (full MAC, confidence, device class, source, SSID/BLE name, channel/RSSI for WiFi or RSSI for BLE, and a sightings count); hold OK from the hit list opens an About screen with attribution. Back returns to the previous screen from either.

Precision rule. FlipDeFlock's core rule carries over unchanged: a bare OUI-prefix match is never shown as a detection on its own, since those address ranges are shared silicon-vendor blocks and would false-positive on ordinary hardware. A hit only counts once corroborated by a Flock-shaped SSID, or when the SSID alone is enough.
Known v1 limitations: no Raven-vs-Falcon GATT disambiguation (Fox ESP32 FW's BLETAGSCAN:FLOCK doesn't yet surface BLE service UUIDs, so BLE hits report as a generic Flock battery unit rather than either model by name); no GPS/mapping, no "guardian" continuous-monitoring mode, no deflock.me QR handoff, no signature-database sync, and no Marauder-flashing UI β€” FoxDeFlock only ever talks to Fox ESP32 Firmware.
Chapter 12

Status Bar WiFi / CC1101 Icon

Your Flipper's own desktop status bar shows a small icon, immediately to the left of the battery indicator, that does double duty: it reflects your ESP32's WiFi connection state as last reported by Fox ESP32 FoxHub's WiFi menu, and β€” only when WiFi isn't connected β€” whether Sub-GHz Garage/Gate/Other has found an external CC1101 module attached. See the FoxFW2.0 guide for what the CC1101 module itself does.

StateAppearance
WiFi connectedThree bold, solid ascending bars β€” always shown first, regardless of the CC1101 module
WiFi not connected, CC1101 module connectedA small antenna glyph
Neither connectedThe same three bars, drawn as thin lines instead of solid β€” still visible, not an error indicator
How this actually works. The Flipper's desktop can't talk to the ESP32 directly while a Fox app has the serial connection open, so instead it polls a small status file on your SD card every two seconds for the WiFi half. Only FoxHub's WiFi menu writes that file β€” Fox Chat and Fox Portal just use whatever WiFi connection already exists and never change it, so that half only ever reflects actions taken through FoxHub's WiFi menu, updated within a couple of seconds of you taking them. The CC1101 half polls a second, separate status file the same way, kept fresh by a small background probe app β€” see the CC1101 paragraph under Sub-Ghz Mode in the FoxFW2.0 guide for exactly when that probe runs.

The icon stays visible even when disconnected on purpose β€” if it vanished entirely, someone who hasn't discovered the Fox ESP32 apps yet would have no hint that this feature exists at all. You can hide it entirely from Settings β†’ Desktop β†’ WiFi/CC1101 Icon β€” that one toggle hides both halves together, not just WiFi.

Chapter 13

Full Command Reference

Every command the firmware understands, sent over serial at 115200 baud. You'll rarely need to type these by hand β€” FoxHub, Fox Chat, and Fox Portal send them for you β€” but they're all reachable from FoxHub's Terminal screen if you want raw access, and knowing them helps make sense of what each menu action is actually doing.

Liveness check. AT replies OK. info replies Fox ESP32 Firmware β€” this exact string is what Fox ESP32 Detector and every app's detection screen look for to confirm they're talking to this firmware and not something else.

WiFi reconnaissance

CommandWhat it does
WIFISCANAPScans for nearby access points, prints AP: lines, ends with SCANDONE
WIFISCANSTA8-second promiscuous sniff for stations (devices), prints STA: lines, ends with SCANDONE
WIFISCANALLRuns both scans in sequence
WIFILIST:AP / WIFILIST:STAReprints the last cached scan without rescanning
WIFISELECT:AP:<index>Selects an AP as the target for AP-info, signal monitor, and attacks
WIFISELECT:STA:<index>Selects a station as the target for targeted deauth
WIFIAPINFO:<index>Detailed info on one scanned AP
WIFICHANNEL / WIFICHANNEL:<1-14>Reads or sets the current WiFi channel
WIFISIGMON10 seconds of live RSSI readings for the selected AP
WIFIPACKETCOUNT5-second promiscuous packet count, replies COUNT:<n>

Sniff modes β€” WIFISNIFF:<mode> (all 8 seconds)

ModePrints
BEACONBEACON:<bssid> rssi:<n> per beacon frame seen
DEAUTHDEAUTH:/DISASSOC:<src>-><dst> β€” spot deauth/disassoc activity nearby
PROBEPROBEREQ:/PROBERESP:<src>
RAWRAW:len:<n> rssi:<n> per frame β€” general traffic volume
MULTISSIDFlags likely beacon-flood activity nearby
PMKIDFlags EAPOL frames seen β€” best-effort frame-shape match, not a parsed PMKID
SAEFlags WPA3 SAE Commit authentication frames β€” best-effort, not a full SAE state machine

MAC address tools

WIFIMAC:GETShows the current station MAC
WIFIMAC:RANDRandomizes the station MAC (software only)
WIFIMAC:CLONE:<mac>Sets the station MAC to a specific address
WIFIMAC:CLONEAPSets the station MAC to the selected AP's BSSID
WIFIMAC:RESETRestores the original factory MAC

Wardriving & packet capture

WIFIWARDRIVEAP scan tagged with your current GPS fix (needs the optional GPS module). FoxHub logs results to /ext/apps_data/fox_esp32/wardrive/wardrive_<YYYY-MM-DD>.csv β€” columns bssid,ssid,latitude,longitude,rssi,channel,encryption_type,timestamp.
WIFIPCAP15-second raw capture, hopping channels 1–11 every 400ms. FoxHub saves a standard .pcap to /ext/apps_data/fox_esp32/captures/capture_<timestamp>.pcap β€” opens directly in Wireshark. Frames truncated to 256 bytes, capped at 150 frames per capture.

WiFi attacks gated

All attack commands below are blocked with ERROR:DISABLED unless SETTINGS:ATTACKS:ON is active. Every attack self-limits to a 5-second burst and ends on its own with ATTACKDONE β€” there's no separate stop command needed.

CommandWhat it does
WIFIATTACK:DEAUTHBroadcast deauth against the selected AP
WIFIATTACK:DEAUTH:<sta-mac>Targeted deauth against one station
WIFIATTACK:BEACON:<ssid1,ssid2,...>Beacon spam cycling your own SSID list
WIFIATTACK:BEACON:RANDOM:<n>Beacon spam with n randomly generated SSIDs
WIFIATTACK:PROBEProbe request flood
WIFIATTACK:RICKROLLBeacon spam using a preset joke SSID list
WIFIATTACK:BADPACKETMalformed/fuzzed beacon-shaped frame burst
WIFIATTACK:CSASpoofed Channel Switch Announcement against the selected AP
WIFIATTACK:SLEEPSpoofed power-save frame against the selected AP + station
WIFIPORTSCAN:<ip>:<start>:<end>Plain TCP connect-scan (also gated), prints PORTOPEN:<port> per open port, ends with PORTSCANDONE. Capped at 100 ports per run.
Deauth/CSA/BADPACKET need WIFISELECT:AP first. SLEEP additionally needs WIFISELECT:STA (run a station scan first).

Bluetooth & Tag Detection

Not available on ESP32-S2 boards (no BLE radio) β€” every command below replies ERROR:Incompatible ESP32-S2 Module has no BLE on that chip.

BLE bridge (general BLE / Chameleon Ultra)

BLEINITStarts the BLE stack
BLESCANGeneral BLE scan (unfiltered)
BLECONN:<mac>Connects to a device
BLESTATUSCurrent connection status
BLEDISCDisconnects
BLESVC:<uuid>Selects a GATT service
BLECHAR:<write-uuid>,<notify-uuid>Selects the write/notify characteristics to use
BLEWRITE:<hex>Writes raw bytes to the selected write characteristic

Incoming notifications arrive asynchronously as NOTIFY:<hex>.

BLE spam gated

BLESPAM:IOSApple proximity-pairing-shaped advertising spam
BLESPAM:WINDOWSWindows Swift Pair-shaped spam
BLESPAM:SAMSUNGSamsung Easy Setup-shaped spam
BLESPAM:ANDROIDFast Pair-shaped spam (alias: BLESPAM:GOOGLE)
BLESPAM:ALLRotates through all four

Each runs an 8-second advertising burst, then ATTACKDONE.

Tag Detection β€” snapshot scans, not a stalking detector

BLETAGSCAN:FINDMY8s scan for Apple Find My broadcasts (AirTag and any other Find My accessory β€” the protocol can't tell them apart) β†’ TAG:FINDMY:<mac> rssi:<n> batt:<full|medium|low|verylow|unknown>
BLETAGSCAN:SMARTTAG8s scan for Samsung SmartTag broadcasts β†’ TAG:SMARTTAG:<mac> rssi:<n>
BLETAGSCAN:TILE8s scan for Tile broadcasts β†’ TAG:TILE:<mac> rssi:<n>
BLETAGSCAN:FLOCK8s scan for Flock Safety external-battery BLE adverts (used by FoxDeFlock) β†’ TAG:FLOCK:<mac> rssi:<n> name:"<name>" mfg:<hex>

Each ends with TAGSCANDONE:<count>. A match means a tag is broadcasting nearby right now β€” it is not a history of whether something has been following you.

HTTP & internet bridge

Bracket-style commands. The GET/POST/PUT/PATCH/DELETE, WiFi, PING, LIST, IP/ADDRESS, and PARSE commands below reproduce the real jblanked/FlipperHTTP wire protocol on purpose β€” verified against that project's own firmware source and against a bundled app's actual request/response parsing code, not just its documentation β€” so any Flipper app built on the standard flipper_http.c client should work against this board without modification. [GET]/ [GET/HTTP]/[POST/HTTP]/[PUT/HTTP]/ [DELETE/HTTP] all reply with the same shape a real FlipperHTTP board uses:

[GET/SUCCESS]{"Status-Code":200,"Content-Length":128}
<response body, raw - may span more than one physical line>

[GET/END]

β€” a status/length header line, the body (sent as-is; any real newlines it contains become extra physical lines, exactly like the official firmware), a blank line, then a method-specific terminator: [GET/END], [POST/END], [PUT/END], or [DELETE/END]. Keep reading until that line shows up rather than stopping after the first one. Note that [GET/HTTP] replies with [GET/SUCCESS] too (not [GET/HTTP/SUCCESS]) β€” the real protocol tags by HTTP method, not by which bracket command triggered the request, so a client can't tell the two apart and neither can this firmware. [PATCH/HTTP] is a Fox-only extension (real FlipperHTTP doesn't define PATCH) and uses its own [PATCH/SUCCESS] / [PATCH/END] pair.

CommandWhat it does
[PING]Replies [PONG]
[LIST]Lists every bracket command the firmware supports, both Fox's own multi-line listing and the exact single-line reply real FlipperHTTP clients send
[REBOOT]Restarts the board
[VERSION]Firmware version string
[WIFI/SCAN]Replies [GET/SUCCESS] / {"networks":["ssid1",...],"details":[{"ssid","rssi","secure"},...]} / [GET/END] β€” networks is the exact key real clients (e.g. FlipWiFi's own scan parser) read; details is a Fox-only extra with the richer per-network data
[WIFI/SAVE]{"ssid":"x","password":"y"}Saves credentials (password optional, for open networks); replies with both Fox's own [WIFI/SAVE/SUCCESS] and the real-spec [SUCCESS] Wifi settings saved. line real clients check for
[WIFI/CONNECT]Tries saved networks in order
[WIFI/CONNECT]{"ssid":"x"}Connects using a saved network's saved password
[WIFI/CONNECT]{"ssid":"x","password":"y"}Connects directly, no prior save needed; success replies with both [WIFI/CONNECT/SUCCESS]<ssid> and [SUCCESS] Connected to Wifi.
[WIFI/DISCONNECT]Disconnects; replies [DISCONNECTED] WiFi has been disconnected. (the exact real-spec line)
[WIFI/LIST]Lists saved SSIDs only, never passwords β€” a deliberate deviation from real FlipperHTTP, which dumps the whole saved-credentials file (including cleartext passwords) unframed; leaking saved WiFi passwords over an exposed serial line wasn't a tradeoff worth making just for byte-parity on a feature most apps don't use
[WIFI/IP]Your public IP β€” does a GET to https://httpbin.org/get and replies with the parsed "origin" field, framed like a GET ([GET/SUCCESS] / origin / [GET/END]); matches the real protocol's exact endpoint and field name
[WIFI/SSID]SSID of the currently connected network
[WIFI/STATUS]true/false β€” connected or not
[IP/ADDRESS]Local IP address, bare (no tag) β€” matches real FlipperHTTP exactly
[WIFI/AP]{"ssid":"x","password":"y"}Starts a WiFi access point (password 8+ characters, or omit for open), replies immediately with the AP's IP β€” not real FlipperHTTP's blocking [AP/CONNECTED]/bridge-until-[AP/DISCONNECTED] loop (some apps, e.g. FlipWiFi's AP feature, expect that specific blocking flow and won't work here β€” Fox Portal's own captive-portal AP mode covers the same ground better anyway)
[GET]<url>Simple GET, returns the response body
[GET/HTTP]{"url":"...","headers":{...}}GET with custom headers
[POST/HTTP] / [PUT/HTTP] / [PATCH/HTTP] / [DELETE/HTTP]{"url":"...","payload":"...","headers":{...}}
[GET/BYTES]<url>Base64-encoded response body β€” binary-safe, but a Fox-only encoding; real FlipperHTTP streams raw bytes over the wire instead, so this one isn't compatible with third-party clients yet
[POST/BYTES]{"url":"...","payload_b64":"..."}Base64-encoded request/response β€” same caveat as [GET/BYTES]
[SOCKET/START]{"url":"wss://host:port/path"}Opens a WebSocket connection
[SOCKET/SEND]<text>Sends a text frame on the open socket
[SOCKET/STOP]Closes the socket; replies with both Fox's own [SOCKET/STOP/SUCCESS] and the real-spec [SOCKET/STOPPED]
[PARSE]{"json":"...","key":"..."}Extracts one flat field from a JSON object, replies with just the bare value (no tag) β€” matches real FlipperHTTP's [PARSE] exactly
[PARSE/ARRAY]{"json":"[...]","index":N}Extracts the Nth element of a JSON array, same bare-value reply
[LED/ON] / [LED/OFF]Controls the status LED

Async WebSocket traffic arrives as [SOCKET/CONNECTED], [SOCKET/DISCONNECTED], [SOCKET/MSG]<text> (or [SOCKET/MSG/BIN]<base64>), and [SOCKET/ERROR]. Everything not covered above still follows Fox's own long-standing shape, [COMMAND/SUCCESS]<data> or [ERROR] <message>.

HTTPS requests do not validate the server's certificate (setInsecure() β€” no root CA store). Fine for casual API calls; don't route sensitive credentials through it.
Known gaps against real FlipperHTTP, kept deliberately rather than missed: [WIFI/LIST] doesn't leak saved passwords (see above), [WIFI/AP] doesn't implement the blocking AP-bridge loop some apps expect, and [GET/BYTES]/[POST/BYTES] are still base64 rather than raw-byte streaming. Deauth-style commands some third-party apps ship their own buttons for (e.g. FlipWiFi's [DEAUTH]) aren't part of the real FlipperHTTP protocol either β€” use FoxHub's own WiFi Attacks menu for that instead.

FoxScript

SCRIPTLISTLists saved scripts
SCRIPTSAVE:<name>:<source>Saves a script (must be a single line β€” see below)
SCRIPTSHOW:<name>Prints a saved script's source
SCRIPTDEL:<name>Deletes a saved script
SCRIPTRUN:<name>Runs a saved script

FoxScript is a small purpose-built scripting language (not JavaScript, though the syntax looks familiar) β€” variables, if/else, repeat(n) loops, numbers, strings, arithmetic/comparison/logical operators, and function calls including dotted native calls. No user-defined functions, arrays, objects, or while/for. Scripts run straight off the ESP32's own storage β€” no SD card, no reflash.

let name = "world";
print("hello " + name);

if (wifi.connect("MySSID", "MyPassword")) {
  let body = http.get("http://api.ipify.org");
  print("my IP is " + body);
} else {
  print("wifi connect failed");
}

repeat (3) {
  print("free heap: " + device.freeHeap());
  delay(1000);
}

repeat is capped at 1000 iterations, and a whole script run is capped at 200,000 evaluation steps as a safety net against a mistyped infinite loop.

Native functions

NamespaceFunctions
(global)print(...), delay(ms)
wificonnect(ssid, password), disconnect(), ip(), ssid(), status(), scan()
httpget(url), post(url, body)
blewrite(hex), connected(), scan(), spam(mode) gated
wifiattackdeauth(), beacon(ssid), portscan(ip, startPort, endPort) gated
gpiomode(pin, mode), write(pin, value), read(pin) β€” any GPIO 0–39
ledon(), off()
storageset(key, value), get(key) β€” small on-device key/value store
devicename(), freeHeap(), uptime(), reboot()
settingsattacksEnabled()
rfid / subghz / ir / gpsPlaceholders today β€” return a "NOTIMPLEMENTED"/"NORFID"-style string rather than touching real hardware. Use the native commands below directly for real RFID/Sub-GHz/IR/GPS access.
Since the serial link is line-based, a saved script has to be one line β€” use ; to separate statements and write loop bodies without literal line breaks, exactly like the example above.

Fox Chat (Discord bridge)

DISCORDPOST:<message>Posts a message to the shared FoxFW Discord channel
DISCORDREADReads the 5 most recent messages
DISCORDREAD:<count>Reads up to <count> messages (max 10)

Reads reply with one DISCORDMSG:<HH:MM>|<full date and time>|<content> line per message (oldest first), ending with DISCORDREADDONE.

Fox AI Chat (Gemini relay)

CommandWhat it does
AIASK:<message>Sends your message to the Gemini relay and waits for a reply β†’ AIREPLY:<text> (newlines escaped as \n), or one of the errors below
AICOOLDOWNReports remaining cooldown seconds without making any network call β†’ COOLDOWN:<n> (0 if clear to send)

AIASK errors: ERROR:NOWIFI, ERROR:EMPTY, ERROR:RATELIMIT:<seconds> (still cooling down β€” the ESP32 enforces this itself before ever reaching the relay), ERROR:BLOCKED (Gemini's own safety filter), ERROR:NOREPLY, or ERROR:HTTP:<code>.

Same shared-relay pattern as Fox Chat's Discord bridge β€” the real Gemini API key lives only in a small relay server FoxFW runs, never on your ESP32 or Flipper. A 60-second cooldown between messages is enforced both by the ESP32 itself and, as a backstop, by the relay server.

Fox Portal

WIFIFOXPORTAL:START:<ssid>:<date>Starts the portal (both arguments can be left blank)
WIFIFOXPORTAL:STOPStops the access point, DNS redirect, and web server
WIFIFOXPORTAL:EXPORTLOGStreams every queued submission back as sequence-numbered LOGFILE:<name>:<count> / LOGLINE:<seq>:<content> / LOGFILEEND:<name>:<count> lines ending in LOGDONE:<files>:<lines> (or just LOGEMPTY if nothing's queued). Deletes nothing by itself. Fox Portal's own menu calls this for you - see "Submission logging" in Chapter 7.
WIFIFOXPORTAL:EXPORTCONFIRMDeletes exactly the files most recently sent by EXPORTLOG, replies OK. The Flipper app only sends this after verifying every count/sequence number above and safely writing the data to its own SD card - see the verification note in Chapter 8.
WIFIFOXPORTAL:SETTITLE:<text>Sets the page heading (built-in default page only)
WIFIFOXPORTAL:SETINTRO:<text>Sets the intro paragraph (built-in default page only)
WIFIFOXPORTAL:SETNOTE:<text>Sets the closing note on the confirmation page (built-in default only)
WIFIFOXPORTAL:SETPAGE:START:<html>Full override of the enquiry-form page
WIFIFOXPORTAL:SETPAGE:THANKS:<html>Full override of the confirmation page (supports {{FIELD:<name>}} placeholders)
WIFIFOXPORTAL:QRReturns WiFi-join text for the currently active SSID

These commands are gated behind SETTINGS:ATTACKS:ON. See Chapter 8 for the full behavior of each β€” the Fox Portal app is the intended way to drive all of this.

Optional hardware β€” RFID, Sub-GHz, IR, GPS

These only work if the corresponding hardware flag was enabled at compile time (FOX_HAS_RFID/FOX_HAS_SUBGHZ/FOX_HAS_IR/FOX_HAS_GPS, all off by default). With a flag off, its whole command family replies a fixed error instead β€” ERROR:NORFID, ERROR:NOSUBGHZ, ERROR:NOIR, or ERROR:NOGPS.

RFID (PN532 breakout, I2C)

RFIDINITStarts the PN532 β€” ERROR:NOTFOUND if it can't be reached
RFIDSCANWaits up to 2s for a tag β†’ UID:<hex>, or ERROR:NOTAG
RFIDREAD:<block>Authenticates (factory default key) and reads a 16-byte Mifare block β†’ BLOCK:<n>:<hex>
RFIDWRITE:<block>:<hex>Authenticates and writes a 16-byte Mifare block β†’ OK
RFIDEMULATE:<uid>Not yet implemented β†’ ERROR:NOTIMPLEMENTED

Sub-GHz (CC1101 breakout, SPI)

SUBGHZINITStarts the CC1101 β€” ERROR:NOTFOUND if it can't be reached
SUBGHZFREQ:<mhz>Sets frequency, 300–928 MHz β†’ OK
SUBGHZRXWaits up to 10s for a raw packet β†’ SUBGHZRX:<hex>, or ERROR:NOSIGNAL
SUBGHZTX:<hex>Sends raw bytes β†’ OK

Raw RX/TX only β€” no rolling-code or OOK protocol decoding.

Infrared

IRSEND:<protocol>:<hex>[:<bits>]Sends a code β€” protocol name e.g. NEC/SONY/RC5, bits defaults to 32 β†’ OK
IRRECVWaits up to 10s for a code β†’ IRRECV:<protocol>:0x<hex>:<bits>, or ERROR:NOSIGNAL
IRTVBGONESends a small starter set of common TV power-toggle codes β†’ TVBGONEDONE

GPS (UART, NMEA 0183)

GPSINITStarts the GPS UART β†’ OK
GPS:FIXFIX:1 or FIX:0
GPS:SATSAT:<count>
GPS:LAT / GPS:LON / GPS:ALTCurrent position β€” ERROR:NOFIX if no fix yet
GPS:DATEDATE:<ddmmyy> TIME:<hhmmss>
GPSTRACKStreams FIX:<lat>,<lon> for 30s as position changes, ends with TRACKDONE
GPSPOI:STARTClears the point-of-interest list and starts marking
GPSPOI:MARK[:<label>]Marks the current fix as a POI β†’ POI:<index> <label> <lat>,<lon>
GPSPOI:ENDStops marking β†’ POICOUNT:<n>
Chapter 14

Safety, Legal & the Attacks Toggle

For authorized security testing and research only. WiFi deauthentication, beacon spam, probe flooding, BLE proximity-pairing spam, and similar tools in this firmware can disrupt networks and devices you don't own. Many jurisdictions treat this as illegal regardless of intent, even against your own equipment if it also affects a neighbor's network. Only point these at networks and devices you own or have explicit, documented permission to test.

The Attacks toggle

All WiFi attacks, BLE spam, the TCP port scanner, and Fox Portal are gated behind one setting, checked with SETTINGS and changed with SETTINGS:ATTACKS:ON / SETTINGS:ATTACKS:OFF β€” reachable from FoxHub's Settings screen as a single "Attacks: ON/OFF" row that applies immediately.

On by default. A fresh device ships with attacks enabled β€” matching how comparable tools like ESP32Marauder behave out of the box. If you'd rather these stay off until you deliberately turn them on, visit Settings right after your first flash and switch it off. The setting is saved to the ESP32's flash and survives reboots, so you only need to set it once.

While attacks are off, every gated command replies plainly with ERROR:DISABLED β€” nothing is hidden or silently ignored.

Built-in self-limits

Every attack primitive (deauth, beacon spam, probe flood, BLE spam, the novelty attacks, the port scanner) runs for a fixed, short burst β€” 5 seconds for WiFi/port-scan attacks, 8 seconds for BLE spam β€” and then stops on its own, replying ATTACKDONE. There's no "run forever" mode and no separate stop command to remember; re-run the command if you want another burst.

Content moderation in Fox Chat

Outgoing Discord messages are checked against a built-in word filter before sending (toggle: SETTINGS:PROFANITY:ON/OFF, on by default), and every post is sent with mentions disabled so @everyone/@here/role pings can never actually ping anyone. See Chapter 6 for the full detail, including what this protection does not cover (Discord's own AutoMod doesn't scan bot-posted messages).

Fox Portal is consent-based

Fox Portal is a lead-capture tool, not a credential-phishing "evil portal" β€” visitors knowingly join an open network and see exactly what they're submitting, with a confirmation page that echoes it back. Don't use it to impersonate another organization's network or to collect information from people who haven't knowingly agreed to give it.

Chapter 15

Known Limitations

An honest list of rough edges, so nothing here catches you by surprise. None of these are dealbreakers for normal use β€” most are "this hasn't been battle-tested against every possible target/accessory yet," not "this is broken."

Firmware

FoxHub

Fox ESP32 Detector

Tag Detection

General

Chapter 16

Support & Troubleshooting

Looking to run a third-party Flipper app that isn't bundled with FoxFW? The FAP Compiler builds a .fap against FoxFW v2.0 straight from a GitHub URL β€” no toolchain install required.

Nothing responds / apps say "not detected"

  1. Run Fox ESP32 Detector first β€” it's built exactly for this. It'll tell you which pin pair and baud rate (if any) something is answering on.
  2. Double-check wiring against Chapter 3 β€” pins 13/14 (USART) or 15/16 (LPUART), plus a shared ground.
  3. Confirm the ESP32 is actually powered β€” a USB cable that only carries data and not power, or a loose connection, is a common culprit.
  4. Make sure the firmware was actually flashed successfully β€” re-run the Web Installer's Erase, then Program again.
  5. If one app detects it but another doesn't, try Connect Settings (reachable from that app's Retry screen) to manually pick the pin pair Detector identified.

qFlipper "Unknown Error" during firmware install

If qFlipper stops at around 23% with "Verifying existing files…" and then shows Unknown Error / "Operation timeout (generic)" on Storage Md5Sum resources.ths, the most common cause is a stale Update folder left on the SD card from a previous install attempt. The checksum qFlipper computed no longer matches what is on the card.

Fix: delete the /Update folder from the root of your SD card (accessible via qFlipper's file browser or the Flipper Mobile App), then try installing again. If you cannot easily locate the folder, formatting the SD card achieves the same result β€” your FoxFW apps and settings will be re-deployed on the next successful install.

Web Installer issues

SymptomLikely cause / fix
Connect button does nothingWeb Serial requires Chrome or Edge on desktop β€” Firefox and Safari don't support it, and it's not available on mobile.
Board isn't in the port list, or "Failed to set control signals"Boards without a USB-to-serial chip (the Flipper Wi-Fi Dev Board and other ESP32-S2 boards) must be in bootloader mode: hold BOOT, tap RESET, release BOOT, then click Connect and pick the port. Also check the cable is a data cable.
"The board didn't answer"Hold the board's BOOT button while you click Connect, and let go once it says Connected.
"That port is being used by something else"Close the Arduino IDE, serial monitors, qFlipper and any other flasher tab, then Connect again.
"Fox ESP32 firmware isn't available for …"The connected chip isn't one Fox ESP32 firmware is built for (ESP32, S2, S3, C3, C5, C6).
Flashing fails partway throughKeep the browser tab in focus the entire time β€” backgrounding it can interrupt the serial transfer. Try a lower baud rate if it keeps failing.
Device unresponsive after flashingPress RESET on the board once, or unplug and replug it β€” a board flashed from bootloader mode sometimes stays there until it is reset. Then verify with AT/info from FoxHub or Detector.

Attacks say "ERROR:DISABLED"

This is the Attacks safety toggle, not a fault β€” turn it on from FoxHub's Settings screen (see Chapter 13).

Fox Chat issues

SymptomLikely cause / fix
"Blocked - message flagged by content filter"Your message matched a word in the built-in filter. Reword it, or turn the filter off via SETTINGS:PROFANITY:OFF if that's intentional.
"Too soon - wait a few seconds and try again."The flood guard β€” wait a few seconds between posts.
Messages post/read fine before you've set up your own botExpected β€” Fox Chat falls back to a pre-configured demo bot/channel until you run Bot Settings. See Chapter 6.
Your own bot doesn't work after Bot SettingsRe-check Message Content Intent is enabled and the bot was actually invited with Send Messages + Read Message History permissions.

Fox Portal issues

SymptomLikely cause / fix
Page looks like a plain generic form, not your custom designstart.html/finish.html were empty or missing when Start ran β€” the ESP32 fell back to its built-in default page. The files are auto-installed to /ext/apps_data/fox_portal/ on a standard qFlipper install; if they're missing, re-install the firmware.
Edits to start.html don't show upEvery Start re-reads all three files fresh, so this shouldn't happen β€” double check you saved to /ext/apps_data/fox_portal/ specifically and re-ran Start (not just Show QR).

General questions

This guide aims to cover everything end to end β€” install, hardware, every app and menu, and the full command set. If something's still unclear after reading the relevant chapter, that's useful feedback: check the project's GitHub Pages site (the same place hosting the Web Installer) for the latest release notes and any additional notes posted there.