# pfodWeb/pfodProxy Startup Instructions

pfodProxy is the usual starting point for running pfodWeb.
pfodWeb.html uses pfodProxy to bridge between it and devices connected via Serial (USB/UART), Classic Bluetooth, BLE (Bluetooth Low Energy), or TCP/IP.
pfodProxy and pfodWeb.html are distributed separately. Download pfodProxy for your OS (see links below) then start pfodProxy and open pfodWeb.html. Leave pfodProxy running in the background while pfodWeb is open.

- Installation and Startup

- Windows
- MacOS
- Linux

- Closing the pfodProxy
- Setting a password
- Multiple Connections
- How to connect a Classic Bluetooth device
- Using a custom port for pfodProxy

## Windows, MacOS and Linux Installation and Startup

## Windows -- 2017 onwards

Download: pfodProxy.exe (also on Github)

1. Double-click pfodProxy.exe. A command window opens and pfodProxy starts listening on port 4989.
2. Open pfodWeb.html in your browser.
3. Leave the pfodProxy window open while you use pfodWeb.

## macOS -- 2017 onwards, Intel and Apple Silicon

Download: pfodProxy-macOS.tar.gz (also on Github)

1. Double-click `pfodProxy-macOS.tar.gz` to extract the .app
2. Double-click pfodProxy.app to start pfodProxy in a Terminal window.
3. Open pfodWeb.html in your browser.
4. Leave pfodProxy running while you use pfodWeb.

macOS Gatekeeper: the first time you run pfodProxy.app, macOS will block it. See detailed macOS setup steps for how to allow pfodProxy through Privacy & Security. This is only needed once.

Terminal control permission: the first time pfodProxy.app runs, macOS will ask "pfodProxyLauncher wants to control Terminal" — click Allow. This is only needed once.

## Linux -- 2017 onwards

Download: pfodProxy (also on Github)

1. Open a terminal in that folder.
2. Make it executable (first time only):

       chmod +x pfodProxy

3. Run it:

       ./pfodProxy

   pfodProxy starts listening on port 4989.
4. Open pfodWeb.html in your browser.
5. Leave the terminal open while you use pfodWeb.

Serial port access: add your user to the `dialout` group so pfodProxy can open USB serial ports without sudo:

    sudo usermod -aG dialout $USER

Log out and back in for the group change to take effect.

## Closing the pfodProxy

Close the pfodProxy manually or use the pfodWeb Close pfodProxy button.
That button will only show when the pfodProxy is running.

## Setting a password

By default pfodProxy accepts requests from any pfodWeb.html on the same machine. If you're concerned about other software/webpages/scripts running on the same machine sending commands to your pfodDevices via the pfodProxy. You can optionally add a pfodProxy password as the second argument, after the port:

    # Windows
    pfodProxy.exe 4989 mypassword

    # macOS (from Terminal)
    pfodProxy.app/Contents/MacOS/pfodProxy 4989 mypassword

    # Linux
    ./pfodProxy 4989 mypassword

Once the pfodProxy password is set, open pfodWeb.html with a matching `?pw=` on its own URL, e.g.:

    file:///path/to/pfodWeb.html?pw=mypassword

The easiest way to use this day-to-day is to create a short cut that launches `pfodProxy.exe 4989 mypassword`, and a bookmark that opens `pfodWeb.html?pw=mypassword`

pfodWeb will display error messages for miss-matching passwords.

## Multiple Connections

You can have more than one pfodWeb window open at once, each connected to a different device — for example one window talking to a serial-connected Arduino, another talking to a second serial pfodDevice, another to a TCP/IP ESP32, and another to a BLE device — all sharing the same pfodProxy running in the background.

1. To open another pfodWeb window, open pfodWeb.html again in your browser (or open a new tab to it) — pfodProxy is already running and will handle the new window.
2. Only one pfodProxy ever actually runs at a time. If pfodProxy is already running, starting it again doesn't start a second copy — it exits silently, leaving the already-running pfodProxy in place.
3. Each pfodWeb window connects to its own device independently — connecting one window to a device doesn't disconnect any other window's device, as long as they're different devices. Two windows can't both connect to the same device at the same time; the second one gets a "Connection Refused" message instead.

## How to connect a Classic Bluetooth device

Classic Bluetooth devices (e.g. HC-05, HC-06) connect via the Serial transport. Pair the device with your computer first using the OS Bluetooth settings, then select the COM port / serial device it creates in pfodWeb.

## Windows

1. Open Settings → Bluetooth & devices → Add device and pair your Classic Bluetooth device.
2. After pairing, open Device Manager → Ports (COM & LPT) to find the new COM port number (e.g. COM5).
3. In pfodWeb select Serial and Classic Bluetooth, click Select COM Port and choose that COM port.

## macOS

1. Open System Settings → Bluetooth and pair your Classic Bluetooth device.
2. After pairing the device appears as `/dev/tty.DeviceName` in the serial port list.
3. In pfodWeb select Serial and Classic Bluetooth, click Select COM Port and choose that port.

## Linux

1. Pair the device using `bluetoothctl`:

       bluetoothctl
       pair XX:XX:XX:XX:XX:XX
       trust XX:XX:XX:XX:XX:XX

2. Bind it to an rfcomm device (replace the address with your device):

       sudo rfcomm bind 0 XX:XX:XX:XX:XX:XX

3. This creates `/dev/rfcomm0` — select it in pfodWeb as a serial port.
4. To release it when done:

       sudo rfcomm release 0

## Using a custom port for pfodProxy

Pass the port number as an argument to change from the default 4989. Update the via pfodProxy host field in pfodWeb to match, e.g. `4990`.

    # Windows
    pfodProxy.exe 4990

    # macOS (from Terminal)
    pfodProxy.app/Contents/MacOS/pfodProxy 4990

    # Linux
    ./pfodProxy 4990

## Security

- Password secured pfodProxy — see Setting a password above. Recommended if you're concerned about other software/webpages/scripts running on the same machine sending commands to your pfodDevices via the pfodProxy. When secured with a password, every request must then carry a matching `&pw=`, checked with a constant-time comparison. A mismatched or missing password is rejected the same way as any other malformed request — silently, with no distinguishing error — so it can't be used for guessing the real password.

The following security features are active even if a password has not been set

- Host header filter — every request to the pfodProxy must carry a `Host` of `localhost:<port>` or `127.0.0.1:<port>`. Any other value (including an attacker's rebinding domain) is rejected with `403 Forbidden` before any handler runs. This is the primary DNS-rebinding defence.
- Loopback-only bind — pfodProxy binds to `127.0.0.1` only, never `0.0.0.0`. It is not reachable from other machines on the network.
- Origin filter — pfodWeb.html opened via `file://` (the normal case) sends `Origin: null` on every request; an ordinary website has its own real origin instead. Any request whose `Origin` is present and isn't `null` is rejected, blocking the common case of some unrelated website's script probing `127.0.0.1` for a running pfodProxy.
- Fixed TCP/IP device port — pfodProxy always connects to a pfod TCP/IP device on port 4989 and never reads a caller-supplied port. This stops an un-secured pfodProxy (no password set) from being usable as a general-purpose port scanner against other hosts on your LAN.
- Cmd syntax validation — every cmd written to a device (Serial, BLE, or TCP/IP) must be a `{...}` pfod command, optionally preceded by a single dedup character, or it's rejected. This stops pfodProxy being used to write arbitrary non-pfod data to a connected device.
- No informative errors — any rejected or malformed request (bad password, bad cmd syntax, wrong port, missing target, unrecognised shape) is met with silence rather than an error response: pfodProxy just doesn't reply, the same as if nothing were listening. This is logged on the pfodProxy console for your own troubleshooting, but nothing is ever sent back that could confirm pfodProxy is running or hint at what failed.

pfodProxy is a single statically-linked rust based binary — no Python, Node.js, or extra packages required.
Source and licensing: https://www.forward.com.au/pfod/pfodWeb