Important: the proxy sends **RPTO to the master only**, not to the hotspot directly. If the proxy is not in the path, you must ensure another mechanism applies **OPTIONS** or you run the server without this proxy path.
> **Prerequisite:** the hotspot must send `PASS=` in its OPTIONS line for
> password login and bidirectional DB sync. If the hotspot sends explicit
> content (TGs, SINGLE, etc.) **without**`PASS=`, the server takes options
> directly from that line and the DB row is ignored. If the hotspot sends no
> RPTO at all (timer expires) or an empty OPTIONS, the server falls back to
> the database.
> See [Hotspot proxy — OPTIONS line behaviour](../server/user-guide/hotspot-proxy.md#options-line-behaviour).
@ -96,6 +96,37 @@ Details of the dashboard flow: [Self-service](../../monitor/self-service.md).
---
## OPTIONS line behaviour
After login (RPTL → RPTK → RPTC), the proxy starts a **10 s timer** waiting for
the hotspot's **RPTO** packet with its **OPTIONS** line. What the hotspot sends
(or does not send) determines **who is the source of truth** for the peer's
static talkgroups:
| Hotspot sends in the RPTO | Who defines the TGs | Behaviour |
|---|---|---|
| `OPTIONS=PASS=xxxxxx;` | **Self-service** (dashboard) | The proxy processes the `PASS=`, verifies the individual password (PBKDF2 against `Clients.psswd`), marks the peer as authenticated, cancels the 10 s timer, and pushes the DB-configured TGs to the master. The user **can** log in by password and auto-login by IP on the dashboard. |
| `OPTIONS=` (empty) | **Self-service** (dashboard) | The proxy reads the TGs from the DB and injects them to the master. The user can **only** use auto-login by IP on the dashboard (no password). |
| **No RPTO at all** (10 s timer expires) | **Self-service** (dashboard) | The proxy assumes the hotspot has no OPTIONS of its own and falls back to the DB. Same effect as `OPTIONS=` empty. |
| `OPTIONS=TS2=730444;SINGLE=0;` (content without `PASS=`) | **The hotspot itself** | The master takes the TGs **directly from the OPTIONS line**. The DB is ignored. The user can **only** use auto-login by IP on the dashboard (no password). |
**Key rule:** self-service is the source of truth **unless** the hotspot sends
explicit content (TGs, SINGLE, TIMER, etc.) in its OPTIONS line. In that case,
what the hotspot says **takes precedence** and self-service is ignored.
### Individual password and dashboard login
- If the hotspot **never** sends `PASS=` in its RPTO, the user **cannot** log in
to the dashboard with a password. They can only use **auto-login by IP**
(if their IP matches `Clients.host`).
- To enable password login on the dashboard, the hotspot must send
`OPTIONS=PASS=your_password;` in its configuration (Pi-Star / WPSD / MMDVM
`optsfile`). The password must match the PBKDF2 hash stored in `Clients.psswd`.
- The `PASS=` flow is what activates bidirectional sync: the proxy stores the
hash, notes the `modified` flag, and pushes the DB-configured TGs to the master.
---
## Hot reload (`SIGHUP`)
**Applied without restart** (active proxy sessions stay up):
Importante: el proxy envía **RPTO solo al master**, no al hotspot directamente. Si el proxy no está en el camino, necesitas otro mecanismo que aplique **OPTIONS** o ejecutas el servidor sin este camino proxy.
> **Prerrequisito:** el hotspot debe enviar `PASS=` en su línea OPTIONS para
> login por contraseña y sincronización bidireccional con la BD. Si el hotspot
> envía contenido explícito (TGs, SINGLE, etc.) **sin**`PASS=`, el servidor
> toma las opciones directamente de esa línea y la fila de la BD se ignora. Si
> el hotspot no envía RPTO (el timer expira) o envía OPTIONS vacío, el servidor
> hace fallback a la base de datos.
> Ver [Proxy hotspot — comportamiento de la línea OPTIONS](../server/user-guide/hotspot-proxy.md#comportamiento-de-la-linea-options).
@ -96,6 +96,38 @@ Detalle del flujo en el panel: [Self-service](../../monitor/self-service.md).
---
## Comportamiento de la línea OPTIONS
Tras el login (RPTL → RPTK → RPTC), el proxy arranca un **timer de 10 s**
esperando el paquete **RPTO** del hotspot con su línea **OPTIONS**. Lo que el
hotspot envíe (o no envíe) en ese RPTO determina **quién es la fuente de
verdad** de los TG estáticos del peer:
| El hotspot envía en el RPTO | Quién define los TG | Comportamiento |
|---|---|---|
| `OPTIONS=PASS=xxxxxx;` | **Auto-servicio** (panel web) | El proxy procesa el `PASS=`, verifica la contraseña individual (PBKDF2 contra `Clients.psswd`), marca al peer como autenticado, cancela el timer de 10 s y empuja los TG de la BD al master. El usuario **puede** hacer login por contraseña y auto-login por IP en el dashboard. |
| `OPTIONS=` (vacío) | **Auto-servicio** (panel web) | El proxy lee los TG de la BD y los inyecta al master. El usuario **solo** puede usar auto-login por IP en el dashboard (sin contraseña). |
| **No envía RPTO** (el timer de 10 s expira) | **Auto-servicio** (panel web) | El proxy asume que el hotspot no tiene OPTIONS propias y hace fallback a la BD. Mismo efecto que `OPTIONS=` vacío. |
| `OPTIONS=TS2=730444;SINGLE=0;` (contenido sin `PASS=`) | **El propio hotspot** | El master toma los TG **directamente de la línea OPTIONS**. Se ignora la BD. El usuario **solo** puede usar auto-login por IP en el dashboard (sin contraseña). |
**Regla clave:** el auto-servicio es la fuente de verdad **excepto** cuando el
hotspot envía contenido explícito (TGs, SINGLE, TIMER, etc.) en su línea
OPTIONS. En ese caso, lo que dice el hotspot **priman** y el auto-servicio se ignora.
### Contraseña individual y login por dashboard
- Si el hotspot **nunca** envía `PASS=` en su RPTO, el usuario **no** podrá
entrar al dashboard con contraseña. Solo podrá usar **auto-login por IP**
(si su IP coincide con `Clients.host`).
- Para habilitar el login por contraseña en el dashboard, el hotspot debe enviar
`OPTIONS=PASS=tu_contraseña;` en su configuración (Pi-Star / WPSD / MMDVM
`optsfile`). La contraseña debe coincidir con el hash PBKDF2 almacenado en
`Clients.psswd`.
- El flujo `PASS=` es lo que activa la sincronización bidireccional: el proxy
almacena el hash, registra el flag `modified` y empuja los TG de la BD al master.
---
## Recarga en caliente (`SIGHUP`)
**Se aplica sin reiniciar** (las sesiones activas del proxy se mantienen):