A free and open-source Android app that unlocks FCC mode on DJI drones when you're using an RC-N1, RC-N2, or RC-N3 controller — the controllers without a screen that connect to your phone via USB cable. If you keep losing signal on your Mini 3 in CE mode, this switches the radio to FCC mode for higher power and more range. No server. No license. No tracking. Just raw DUMPL commands from a JSON profile file.
This software is provided for educational and research purposes only. Modifying radio transmission parameters may violate laws and regulations in your country or region. In most places, increasing radio power beyond what is legally permitted for your area requires authorization from the relevant regulatory authority.
You are solely responsible for ensuring that your use of this software complies with all applicable local, regional, and national laws. The author of this project accepts no liability for any damage, legal consequences, or regulatory action arising from the use of this tool.
Use only if you have proper authorization to operate in FCC mode in your jurisdiction. If you are unsure whether this is legal where you live, do not use it.
This project is not affiliated with, endorsed by, or sponsored by DJI. Using this tool may void your warranty and DJI Care Refresh coverage.
If FreeFCC USB helped you out, please consider buying me a coffee. It helps cover server costs and keeps development going.
This app has not been tested on a real drone yet. The DUMPL frames are based on the publicly documented dji-firmware-tools protocol. If you test it, please open an issue and let me know the result.
If you're flying a Mini 3 (or any DJI drone) with the stock RC-N1 controller in a CE region, you've probably noticed the signal drops out well before the advertised range. CE mode caps the radio power at 0.5W on 2.4GHz; FCC mode allows 2W. That's a 4x power difference.
This app switches the radio from CE to FCC mode over the USB cable between your phone and the RC-N1/RC-N2/RC-N3.
For smart controllers (RC2, RC Pro, RC Plus — the ones with a built-in screen) — use FreeFCC instead. That app runs directly on the controller and connects via TCP.
Other free FCC tools do not work on the Mini 3 for two reasons:
Other tools use USB host mode (the phone is the USB host, the RC is a device). But the Mini 3's RC-N1 firmware only accepts DUMPL commands over Android Open Accessory (AOA) mode — where the RC is the USB host and the phone is the accessory.
FreeFCC USB uses AOA accessory mode — the RC-N1 presents as a USB accessory with manufacturer="DJI", the app calls UsbManager.openAccessory() to get a ParcelFileDescriptor, and reads/writes raw DUMPL bytes via FileInputStream/FileOutputStream.
Other tools send only 2 hardcoded byte arrays — a fragment of the full FCC unlock sequence. One is just frame 9 of 21 (the 2.4GHz power limit write). It's missing the service-mode handshake, the region commit, and the 5.8GHz power limit.
The Mini 3's firmware requires the full 21-frame sequence: enter service mode → set region to FCC → write both band power limits → commit → exit service mode.
FreeFCC USB sends the complete 21-frame universal profile, wrapped in the RCLink envelope that the RC-N1's AOA parser expects, with a bootstrap handshake and keepalive frames to keep the session alive.
The RC-N1 has two USB-C ports that work differently:
| Port | What it does | USB mode | Used for |
|---|---|---|---|
| TOP port (phone cradle) | DJI Fly connects here for video/telemetry/flight | AOA accessory (RC is host, phone is accessory) | FCC patch + normal flight |
| BOTTOM port (charging) | Charging and service access | USB host mode (phone is host, RC is device) | Charging only on Mini 3 |
For the Mini 3, the FCC patch must be sent through the TOP port using AOA accessory mode. This is the same port you normally use for DJI Fly — but you need to close DJI Fly first because Android only allows one app at a time to hold the USB accessory.
The app:
- Opens the AOA accessory on the TOP port
- Sends a bootstrap handshake (2 frames) to initialize the DUMPL command session
- Sends keepalive frames every 2.5s to keep the session alive
- Sends the 21-frame FCC unlock sequence, each wrapped in an RCLink envelope
- The RC-N1 forwards the commands to the drone over the radio link
| Feature | Description |
|---|---|
| FCC Unlock | Switches the radio from CE to FCC mode for higher power and more channels |
| CE Restore | Reset to factory region (or just reboot the controller) |
| Auto-FCC | Toggle to automatically connect and apply FCC every time the app opens |
| Offline | Everything runs locally. No internet, no server, no tracking |
| Open Profile | The command frames are a plain JSON file you can inspect and edit |
| No License | No activation, no trial, no tracking, no server contact |
Designed for: USB-cabled controllers without a screen (RC-N1, RC-N2, RC-N3) + phone/tablet.
| Controller | Transport | Status |
|---|---|---|
| RC-N1 (TOP port, AOA) | USB Accessory (AOA) | Untested — should work |
| RC-N2 (TOP port, AOA) | USB Accessory (AOA) | Untested — should work |
| RC-N3 (TOP port, AOA) | USB Accessory (AOA) | Untested — should work |
The FCC profile is universal — the same 21-frame DUMPL sequence works on every DJI aircraft:
| Drone | FCC |
|---|---|
| Mini 3 | ✅ |
| Mini 3 Pro / Mini 4 Pro / Mini 5 Pro | ✅ |
| Mini 2 / Mini 2 SE / Mini 4K / Mini (Mavic Mini) | ✅ |
| Air 3 / Air 3S / Mavic Air / Air 2 / Air 2S | ✅ |
| Mavic 3 / Classic / Pro / Mavic 4 Pro | ✅ |
| Mavic Pro series / Mavic 2 Pro/Zoom | ✅ |
| Avata / Avata 2 / FPV Racer / FPV Racer 2 / Flip / Neo / Neo 2 | ✅ |
| Phantom 4 STD/ADV/PRO/PRO V2/MS / Inspire 2 / Spark | ✅ |
Important: You need to repeat these steps every time you turn on the drone and/or remote. FCC mode is a RAM-only setting — it reverts to the factory region on power cycle.
- An Android phone or tablet (Android 7.0+)
- A USB-C cable
- Your DJI drone with RC-N1, RC-N2, or RC-N3 controller
- The FreeFCC USB app (download from releases)
- Download the
FreeFCC-USB.apkfrom the releases page - Install it on your Android phone (you may need to enable "Install unknown apps" in your security settings)
- Turn on the drone
- Turn on the RC-N1/RC-N2/RC-N3 controller
- Wait a few seconds for them to connect (the controller's status LED should turn green)
This is critical. Android only allows one app at a time to hold the USB accessory connection. If DJI Fly is running (even in the background), it will claim the accessory and our app won't be able to write.
- Go to Settings → Apps → DJI Fly → Force Stop
- Make sure DJI Fly is completely closed (not just swiped from recents)
- Take your USB-C cable
- Connect one end to your phone
- Connect the other end to the TOP USB-C port of the controller (the one in the phone cradle where you normally plug in for DJI Fly)
Why the TOP port? The TOP port is where the RC-N1 presents as an AOA USB accessory. The BOTTOM port is for charging and uses a different USB mode. The Mini 3's firmware only accepts DUMPL commands over the AOA accessory connection on the TOP port.
- Open the FreeFCC USB app on your phone
- Tap the Connect button
- If prompted, grant USB permission (a dialog will appear — tap "Allow")
- The connection status should change to "Connected" (green indicator)
If it says "Controller not found": Make sure DJI Fly is force-closed. Make sure you're plugged into the TOP port. Try unplugging and replugging the USB cable.
- Once connected, tap the Enable FCC Mode button
- Wait for the progress bar to complete. Each apply sweeps every command path that is known to work on some hardware, then keeps re-applying in the background
- You should see a green checkmark and "FCC applied"
- Open the Log tab and look for a line like
profile@82: 3 responses. That tells you which path your controller answered on — worth including if you file an issue
Tap Release USB for DJI Fly. While this app holds the USB accessory, DJI Fly cannot connect to the controller — the accessory is exclusive to one app at a time. Releasing hands the port back without unplugging the cable.
Background repeat stops when you release. If the radio flips back to CE, tap Reconnect and apply again.
- Keep the USB cable connected to the TOP port (don't switch ports)
- Open DJI Fly
- Go to the Transmission tab (the satellite/signal icon)
- Look at the horizontal signal bar around -90 dBm:
- If it lines up with the 1km mark, your drone is still in CE mode (it didn't work)
- If it falls below the 1km mark (the signal extends further), your drone is in FCC mode ✅
Check the images below for reference:
| FCC Mode | CE Mode |
![]() |
![]() |
| Signal extends past 1km | Signal barely reaches 1km |
If the signal graph shows FCC mode, you're done. Go fly and enjoy the extra range.
To revert to CE mode: Either tap "Stop FCC Mode" in the app, or simply power cycle the controller and drone — FCC mode is RAM-only and reverts to the factory region on reboot.
| Problem | Solution |
|---|---|
| "Controller not found" | Force-close DJI Fly (Settings → Apps → DJI Fly → Force Stop). Make sure you're on the TOP port. Try a different USB-C cable. |
| "FCC apply failed" | The DUMPL writes failed. Make sure the drone is powered on. Try disconnecting and reconnecting, then tap Connect again. |
| "Patched but still in CE mode" | Apply again — some combinations take it on the second pass. Then check the Log tab: if every path shows 0 responses, the controller is not relaying to the aircraft, which is different from FCC being rejected. Please open an issue with your drone model, controller model, firmware versions, and those log lines. |
| DJI Fly won't connect after applying | Tap Release USB for DJI Fly. Only one app can hold the USB accessory at a time. |
| Back in CE mode after going outside | Some aircraft reset the region when they set the home point on GPS lock. Reconnect and apply again once you have GPS. |
| USB permission dialog doesn't appear | Unplug and replug the USB cable. Or go to Settings → Apps → FreeFCC USB → Permissions. |
| DJI Fly keeps auto-launching | Go to Settings → Apps → DJI Fly → Open by default → Clear defaults. |
If FreeFCC USB helped you out, please consider starring the repo and buying me a coffee.
The app sends DUMPL commands to the controller over the USB cable using Android Open Accessory (AOA) mode. DUMPL is DJI's internal command protocol, publicly documented in the dji-firmware-tools project.
The RC-N1/RC-N2/RC-N3 uses the Android Open Accessory protocol. In this mode:
- The controller is the USB host (it initiates the AOA handshake)
- The phone is the USB accessory (it enters accessory mode)
- The app calls
UsbManager.openAccessory()to get aParcelFileDescriptor - Raw DUMPL bytes are written via
FileOutputStreamand read viaFileInputStream
DUMPL frames are not sent raw — each frame is wrapped in an 8-byte RCLink envelope:
[0x55][0xCC][0x49][0x57][4-byte LE length][DUMPL frame bytes...]
The RC-N1's AOA parser expects this envelope format. The magic bytes 0x55 0xCC signal an RCLink frame, followed by route bytes 0x49 0x57 ("IW"), the payload length, and the inner DUMPL frame.
Immediately after opening the AOA accessory, the app sends 2 bootstrap frames:
- CONN_BOOTSTRAP_3100 — destination component 0x1F, payload
{0x00, 0x00, 0x01} - CONN_BOOTSTRAP_0000 — destination component 0x00 (broadcast), payload
{0x00, 0x00, 0x01}
These initialize the DUMPL command session. Without this handshake, the controller ignores all subsequent commands.
The app sends 2 keepalive frames every 2.5 seconds to keep the RCLink session alive:
- Destination 0x06, cmd_set=6, cmd_id=0x77, payload
{0x01, 0x01, 0x00, 0xFF, 0xFF, 0x20, 0x00, 0x00} - Destination 0x0E, same payload
Without these keepalives, the controller may drop the session before the FCC sequence completes.
21 frames sent in 2 rounds, each wrapped in the RCLink envelope:
- Enter service mode (AUTOTEST → SVO)
- Set radio region to FCC
- Write flight-controller region parameters
- Set country codes
- Set 2.4GHz and 5.8GHz channel groups
- Set OFDM power limits for both bands
- Write WIFI channel map and flags
- Toggle flight-controller parameters
- Set RADIO parameters
- Commit the region change
- Exit service mode
The same 21 frames go to every DJI aircraft model — the profile is universal.
Timing matters. Frame 1 opens the service-mode window and frame 21 closes it. Everything in between has to land inside that window, which is why the profile uses a 30ms inter-frame delay — one round takes about 0.65s. Stretch the sequence out over several seconds and the radio silently stays on CE even though every write "succeeded".
One apply sweeps several paths. Which sender byte and which command the radio
accepts turns out to vary across aircraft, controller and phone. Rather than
guessing, each apply sends the profile as 0x82, then as 0x02, then the
single-command WLM switch, and counts responses for each so the Log tab shows
which one your hardware answered on. Passes are independent, so a path your
hardware ignores costs nothing but its own runtime.
The profile is a JSON file in app/src/main/assets/profiles/fcc.json:
{ "s": 16, "i": 88, "d": 18, "p": "030100", "note": "Enter service mode" }| Field | Meaning |
|---|---|
s |
Command set (16 = service mode, 6 = radio, 3 = flight controller) |
i |
Command ID within the set |
d |
Destination device |
p |
Payload as hex string (sent as raw bytes) |
note |
Plain English description |
You can open this file in any text editor, read every byte that gets sent, and modify it if you want.
app/src/main/
assets/profiles/
fcc.json 21 frames, FCC unlock (universal)
ce_restore.json 1 frame, reset to factory region
java/com/freefcc/n1/
DumplBuilder.kt Frame builder (CRC-8/16 tables)
DumplTransport.kt AOA accessory transport + RCLink envelope + TX thread + keepalives
ProfileLoader.kt JSON profile loader
FccViewModel.kt State management + bootstrap handshake + FCC logic
MainActivity.kt Compose UI
res/
drawable/ Launcher icon (vector)
mipmap-anydpi-v26/ Adaptive icon
values/ Theme + strings
xml/ Network security config + accessory filter
Requirements: Java 17+, Android SDK 35.
java -classpath gradle\wrapper\gradle-wrapper.jar org.gradle.wrapper.GradleWrapperMain assembleRelease --no-daemonAGPL-3.0. See LICENSE.
The DUMPL protocol implementation is based on the publicly documented dji-firmware-tools project (GPL-3.0).
- GitHub Issues: github.com/doesthings/FreeFCC-USB/issues
- Ko-fi: ko-fi.com/freefcc

