The staged spike that worked out the VDA call order is no longer part of the build. It is kept at tag spike-final. - src/main.c is the service only: instance lock, credentials, MBus and pad init, then the web service. src/server.c and include/c4f_server.h are gone with stage 8, and so are the stage-only helpers in src/vda.c: the MBus bind and holds, the assignment and button-map probes, and the GoldHEN klog stream path. The service reads /dev/klog, which is what works. - VERSION holds the only version number. Both Makefiles pass it in, the packager reads it for param.sfo and the package name, and the build and deploy scripts read it for the file they look for. - The payload's log is /data/control4free/control4free.log, not spike.log. - The page drops the protocol 1 branches: the payload has always answered 2. A console slot is a "controller" and a pad plugged into the phone or PC is a "gamepad", so the two no longer read as the same word. - The host tests move to tests/, with tests/run.py to run all four suites. They build the real sources with the PS4 calls stubbed, so they need no console. klog_test now covers the device path only, and asserts that nothing ever connects to GoldHEN's klog server.
9.2 KiB
Control4Free
A GoldHEN payload for controlling the PS4 from a phone or PC, using touch, keyboard, or an Xbox/other controller exposed by the browser's Gamepad API. Virtual controllers use the PS4's native user-selection screen, so they work on the home screen, at sign-in and in games.
Status: browser control, native user sign-in, gameplay, the launcher, GoldHEN AutoRun and recovery after rest mode have been confirmed on the development console. Four virtual slots are exposed; the console's device limits apply.
Requirements
- A PS4 running GoldHEN. Development console: firmware 10.01, GoldHEN 2.4b18.10. Starting Control4Free from GoldHEN itself (LaunchPad or AutoRun) needs 2.4b18.10 or later; the launcher app and PC sending need PayLoader.
- Nothing connected to GoldHEN's klog viewer while you add a controller. Control4Free reads the kernel log itself to recover a new device's handle, and the log has a single reader.
- A phone or PC on the same network.
- Turn off other GoldHEN controller plugins in games you play with Control4Free. A plugin that takes over a signed-in user's controller can stop games from reading the virtual controllers.
Install
- Copy
build/Control4Free-<version>.pkgto a USB drive (or to/data/pkg/over GoldHEN's FTP server) and install it with GoldHEN's Package Installer. - Open Control4Free from the home screen and press Cross once. The app adds Control4Free to GoldHEN's AutoRun (GoldHEN 2.4b18.10 or later), so GoldHEN starts it every time it loads. It also starts it right away if GoldHEN's PayLoader is on; otherwise restart the PS4 and run the jailbreak again.
- Scan the QR code or enter the address on your phone or PC. Select a controller there and sign in through the PS4 screen.
The app stays useful afterwards: it shows whether Control4Free is running, its address and QR code, and how many controllers are connected.
- Cross starts Control4Free when it is not running (PayLoader must be on).
- Triangle turns GoldHEN's auto-start on or off, or updates it after you install a newer package.
- Square, then Cross, stops Control4Free and disconnects its controllers.
- Circle closes the app. Control4Free keeps running without it.
Without the app
GoldHEN's own Payloader LaunchPad (under Utilities) does the same job:
-
Put
control4free.elfin/data/payloads/on the PS4, for example through GoldHEN's FTP server (port 2121). -
In the LaunchPad, select
control4free.elfto start it, or press Square on it to add it to the AutoRun queue. The queue is/data/GoldHEN/payloads.ini:[AutoRun] /user/data/payloads/control4free.elf = 1
When you update Control4Free this way, replace /data/payloads/control4free.elf.
Upgrading from the original test payload: use Stop Control4Free in the controller page's menu, or restart the PS4. That old version has no launcher API, so the app will not start a second copy over it.
Rest mode: the service closes stale connections and rebuilds its listener after socket failures or a long pause. Queued input is discarded, and disconnected controllers report neutral input. Reopen the controller page and select your controller after waking; an unused controller is removed after the reconnect grace period. This can recover a surviving payload's network service; it cannot revive a host process that the console terminated or stopped running. When upgrading a stuck older instance, restart the PS4 and load GoldHEN again.
Kernel logs: controller sign-in is detected in the PS4's kernel log, which
has a single reader. Control4Free opens /dev/klog only while a controller is
waiting for sign-in and releases it afterwards, so GoldHEN's klog server works
the rest of the time. It does not use GoldHEN's klog stream: GoldHEN serves one
client at a time and, after one leaves, can go minutes without serving the next.
If a klog viewer is connected to GoldHEN when you add a controller, the page
says so; close the viewer and try again.
Diagnostics are saved at /data/control4free/control4free.log, with elapsed timestamps
such as [c4f] [+00:01:23.456]; the PS4's calendar setting is not used. Starting
a new instance preserves the last run in control4free.log.previous. A heartbeat every
minute and explicit network recovery messages help locate any remaining hang.
Use
- Stop any older Control4Free payload before loading another. They all use port 4264.
- Start Control4Free: from GoldHEN (above), from the launcher app, or by sending
build/control4free.elffrom a PC to GoldHEN's PayLoader on port 9090 with a payload sender. The payload serves its own page; no PC web server is needed. - Open
http://YOUR-PS4-IP:4264in the phone or PC browser. - Select a free controller. This creates it and opens native PS4 user selection. Use Left/Right and Cross to select a user or follow the PS4's guest flow. Do not press PS while the initial user-selection screen is open: in the hardware experiment this cancelled selection. PS works after sign-in.
- Test the home screen and then a game before adding another controller.
For an Xbox or other physical controller, connect it to the phone/PC, press a button so the browser detects it, then choose its virtual-controller slot under connected controllers. Sign it in through the same PS4 screen. Add and sign in controllers one at a time. Touch and keyboard can also operate the selected slot.
The corner menu provides local layout/keyboard preferences, Disconnect controller, and Stop Control4Free. PS and Share send actual controller buttons. The PS4 assigns users; there are no user settings on the page.
Some browsers restrict Gamepad API access on an HTTP page. If the page reports
that restriction, try opening a saved copy of client/index.html locally and
entering YOUR-PS4-IP:4264 in its connection settings. Browser support for local
files varies. Keep the controller page in the foreground while playing.
Connection behavior
- Opening the page does not create a controller. Creation follows an explicit controller selection; the payload never presses sign-in buttons automatically.
- Each virtual slot has one browser owner. Multiple local inputs may share that browser's selected slot, or use separate slots.
- A lost connection releases held buttons. After 3 seconds without updates, inputs become neutral; after 15 seconds the controller is removed. A short disconnect leaves a 15-second window to select that controller again.
- Explicit disconnect removes the controller immediately. Stopping the payload removes all controllers and restores the saved host credentials. Browser Stop refuses while another browser owns a controller. The launcher's confirmed Stop can disconnect all controllers through its launcher API, which websites cannot use.
- If the kernel log is not available yet when Control4Free starts (AutoRun can start it early), it connects to it when the first controller is created.
- There is no time limit. Rebooting the console ends it; AutoRun, the launcher or a PC starts it again.
Build
The ps4-payload-sdk toolchain is pinned in the Docker image:
docker build -t control4free-build docker/
docker run --rm -v "$PWD:/src" -w /src control4free-build make
Output: build/control4free.elf, with the compressed page embedded. The version
comes from the VERSION file at the top of the repository.
To build the installable launcher after the payload image is available:
docker build -t control4free-launcher-build -f docker/Dockerfile.launcher docker/
docker run --rm -v "$PWD:/src" -w /src control4free-launcher-build bash -lc 'make && make -C launcher'
The host test suites build the real sources with the PS4 calls stubbed, so they need no console:
docker run --rm --network none -v "$PWD:/src" -w /src control4free-launcher-build python3 -B tests/run.py
Output: build/Control4Free-<version>.pkg (title ID CFRE00001). On Windows,
tools/build-launcher.ps1 runs both image builds and the package build. It does
not send anything to a console. Packaging uses OpenOrbis and LibOrbisPkg. The
launcher draws its screen and its icon in software, in the controller page's style.
Current limits
Rumble, lightbar feedback and motion input are not implemented. Multiple native
user sessions are unverified. User-assignment status comes from kernel-log events
and may lag or miss an event; check the TV.
Logs are written to /data/control4free/control4free.log on the console.
Credits and license
The VDA code is ported from seregonwar/SplashDown. The build uses John Törnblom's ps4-payload-sdk and the OpenOrbis PS4 Toolchain. Ghostcontrol was a research reference. JSON parsing uses jsmn; the launcher uses QR Code generator, stb_truetype and the Roboto font.
GPL-3.0; see LICENSE and THIRD_PARTY.md.