# CastBridge — Hotel Install Guide (guest casting on your own hardware)

This guide is for hotel IT installing the **CastBridge** appliance so guests can
cast **YouTube / Netflix** from their phone (iPhone *and* Android) to the TV in
**their own room** — and only their own room.

> **What you need from us:** your **Customer ID** (shown on your hotel's page in
> the Hotel TV portal) and the one-line install command (also on that page, with
> your Customer ID already filled in). That's it.

---

## 1. How it works (1 minute)

Guest phones are on the **guest Wi-Fi**; the TVs are on a **separate network**.
Normally a phone can't even *see* a TV on another network, and if it could, it
could cast to *any* room. CastBridge solves both:

- It's a small always-on Linux box (your hardware) with **two network
  connections** — one to the **guest network**, one to the **TV network**.
- A guest scans the QR on their room TV → links their phone → from then on their
  phone sees **only that TV** and casts to it.
- All casting goes **through the appliance**, which only ever connects a phone to
  the **TV it paired with**. A guest can never reach another room's TV.

You do **not** need per-room VLANs, and you do **not** need to add any casting
rules to your router. The appliance is self-contained.

---

## 2. What you need

- **A small Linux PC** (mini-PC/NUC class is plenty — 2 cores, 2 GB RAM, 16 GB
  disk). Ubuntu 22.04+ recommended. One per property.
- **Node.js 20+** installed:
  ```bash
  curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
  sudo apt-get install -y nodejs
  ```
- **Two network connections** on that box:
  - **TV leg** — same network/VLAN as the room TVs.
  - **Guest leg** — same network/VLAN as the guest Wi-Fi.
  - These can be **two physical NICs** (e.g. `eth0` + `wlan0`) or **one trunk
    port with two tagged VLANs** (e.g. `eth0.30` + `eth0.20`). Either is fine.
- Your **Customer ID** (from the portal — see step 3).

---

## 3. Get your install command from the portal

1. Sign in to the Hotel TV portal and open **your hotel's page**.
2. Find the **Guest Casting** section — it shows your **Customer ID** and a
   ready-to-paste **install command with your Customer ID already in it**, e.g.:

   ```bash
   curl -fsSL https://ota.mndev.co.za/castbridge/install.sh \
     | sudo bash -s -- cust_XXXXXXXX <tvInterface> <guestInterface>
   ```

   Replace `<tvInterface>` / `<guestInterface>` with the two network interface
   names on your box (find them with `ip -br addr`). Examples:
   - Two NICs: `... cust_XXXXXXXX eth0 wlan0`
   - Trunk + VLANs: `... cust_XXXXXXXX eth0.30 eth0.20`

> The Customer ID is what binds this appliance to **your hotel**. Casting only
> works for a Customer ID we've provisioned for you — see *Licensing* below.

---

## 4. Install

Paste the command from the portal and run it. It will:
- install the CastBridge service to `/opt/castbridge`,
- write its config to `/etc/castbridge/env` (your Customer ID + the two
  interfaces),
- install and enable a **systemd service** (`castbridge`) that starts on boot,
- start it.

On success you'll see `✓ CastBridge running` and the appliance's IP addresses.

---

## 5. Verify it's working

On the appliance:
```bash
# Service up?
systemctl status castbridge --no-pager

# Health (should show your customerId + a TV count)
curl -s http://localhost:8443/health        # -k https:// if you didn't set HTTP-only

# Live log
journalctl -u castbridge -f
```
You should see lines like `[tv-registry] discovered <Room> TV ...` as it finds
the room TVs, and `[cast-proxy] listening ... (per-phone -> paired TV)`.

**End-to-end test (do this with one TV + one phone):**
1. On the phone (on guest Wi-Fi), scan the room's on-screen QR → tap **Link this
   TV**.
2. Open **YouTube** → tap **Cast** → after a few seconds the room TV appears →
   tap it → a video should play on that TV.
3. Confirm isolation: a *second* phone that paired a *different* room must **not**
   be able to cast to the first room's TV.

---

## 6. Updating

Re-run the same install command (it's idempotent — safe to re-run). It pulls the
latest CastBridge, keeps your config, and restarts the service.

---

## 7. Network notes (for your firewall, optional)

- **Required:** nothing. The appliance bridges discovery and proxies the cast
  itself; your router needs no casting rules.
- **Recommended hardening:** if your guest network can currently route to the TV
  network, add **one** rule — *deny guest network → TV network*. The appliance
  doesn't need that path (it has its own leg on each side), and blocking it
  guarantees guests can't bypass the appliance to reach a TV directly. Most guest
  networks already isolate guests this way.
- **Pairing page:** served on port **8443** over plain HTTP (so guests don't hit
  a certificate warning on a closed network). Guests reach it on the **guest
  leg** only.

---

## 8. Troubleshooting

| Symptom | Check |
|---|---|
| TV never appears in the cast list | Phone must **scan the room QR and link first**; opening YouTube alone won't show it. Then give it a few seconds / reopen the app. |
| `health` shows `customerId: null` | The Customer ID wasn't set — re-run the install command with your ID (from the portal). |
| TVs not discovered (`tv-registry` shows none) | The **TV leg** isn't on the TVs' network, or mDNS is blocked on that segment. Confirm the interface name and that the box can reach a TV (`ping <tv-ip>`). |
| Pairing page won't load on the phone | The phone can't reach the appliance's **guest leg** — confirm the guest interface IP and that guests can reach it on port 8443. |
| Cast starts then drops | Usually fine for YouTube/Netflix (TV streams from the internet). If persistent, check the appliance can reach the TV on ports 8008/8009. |

Logs: `journalctl -u castbridge -n 100 --no-pager`

---

## 9. Licensing

CastBridge is bound to your **Customer ID** and checks in with the Hotel TV
backend. Casting only works for a Customer ID we have **provisioned and that has
an active subscription** — the pairing codes guests scan are minted and validated
by our backend per customer. A copied appliance with no valid, active Customer ID
will not cast. If a subscription lapses, casting stops; reactivating restores it.

---

*Internal reference: the appliance is the `castbridge/` service; installed via
`castbridge/scripts/install.sh <customerId> <tvIface> <guestIface>`. Config lives
in `/etc/castbridge/env`. See `project_castbridge_office_testbed` notes for the
architecture and the cast-proxy design.*
