# Meshagora — Deployment & Troubleshooting --- ## Version History ### v0.2 — IP Detection & Startup Transparency - Replaced UDP routing trick with `ifconfig` parsing for hotspot IP detection. The UDP trick failed on the Samsung A25 (and likely other Android builds) because the hotspot interface routing entry may not exist at startup. `ifconfig` reads interface addresses directly via socket ioctls — no netlink, no root, no routing assumptions. - Startup banner now lists all detected non-loopback IPs with interface names, so if the primary guess is wrong the alternatives are immediately visible. - Added `install_termux.sh` — one-shot setup script for Termux. - Added `net-tools` as an explicit dependency (`ifconfig` provider). ### v0.1 — Initial prototype - Single-file Flask app, in-memory SQLite, runs on Android/Termux hotspot. --- ## Dependencies ### Termux (Android) — required packages | Package | Source | Purpose | |---------|--------|---------| | `python` | `pkg` | Runtime | | `net-tools` | `pkg` | `ifconfig` — hotspot IP detection | | `libjpeg-turbo` | `pkg` | JPEG support for Pillow (required by `qrcode[pil]`) | | `libpng` | `pkg` | PNG support for Pillow (required by `qrcode[pil]`) | | `flask` | `pip` | Web framework | | `qrcode[pil]` | `pip` | QR code generation at `/qr` | ### Desktop (testing only) | Package | Source | Purpose | |---------|--------|---------| | `flask` | `pip` | Web framework | | `qrcode[pil]` | `pip` | QR code generation | `ifconfig` is standard on desktop Linux/macOS — no extra install needed. --- ## Quick Start (Termux) **First time only — install dependencies:** ``` bash install_termux.sh ``` Or manually: ``` pkg install python net-tools libjpeg-turbo libpng pip install flask "qrcode[pil]" ``` **Every session:** 1. Enable Android mobile hotspot. 2. Open Termux and run: ``` python3 meshagora.py ``` 3. Read the startup banner — note all three keys and the Join URL. 4. Open `http://[IP]:5000/qr` on the server device and display it for participants to scan. 5. Once everyone has joined, go to `/admin` → HIDE QR. --- ## Starting the Server 1. **Enable the Android mobile hotspot before running the script.** IP detection reads active interfaces at startup — if the hotspot is off, the banner URL will be wrong. 2. Run: ``` python3 meshagora.py ``` 3. The startup banner prints: ``` ================================================== MESHAGORA v2.3 — SOCIAL SANDBOX Admin Post Key : [4 emoji] Trusted Post Key : [2 emoji] Default Post Key : [2 emoji] -------------------------------------------------- Join URL : http://192.168.43.1:5000/join (wlan0) Also try : http://10.0.2.5:5000/join (rmnet0) QR code : http://192.168.43.1:5000/qr If no URL works, run: ifconfig | grep inet ================================================== ``` Write down or photograph all three keys. They cannot be recovered without restarting the server (which destroys the session). **Reading the banner:** - "Join URL" is the best-guess hotspot address (`192.168.x.x` preferred). - "Also try" lines show other detected interfaces. The `rmnet` / `10.x.x.x` entries are mobile data — participants on the hotspot WiFi cannot reach those. - Samsung A25 hotspot is typically `192.168.43.1` on `wlan0`. 4. Navigate to `http://[IP]:5000/qr` on the server device and display the QR code for participants to scan. 5. Once all participants have joined, hide the QR code from the Admin Panel (`/admin` → HIDE QR). --- ## Connecting Participants Participants need to: 1. Join the hotspot WiFi (name set by the server device's hotspot settings). 2. Open a browser and scan the QR code, or type the Join URL from the banner. 3. Go to `/join` — choose a username, Profile Key (2 emoji), and Friend Key (2 emoji). No app install required. Works on any browser from Android 7.0+, iOS Safari, desktop Chrome/Firefox. --- ## Admin Panel Navigate to `/admin` from any browser connected to the hotspot. Enter the 4-emoji Admin Post Key when prompted. Authentication persists for that browser session. **Actions available:** - Restrict / Unrestrict / Promote / Demote individual users - View the current Default Post Key (large, readable — copy to board or announce verbally) - Rotate Default Key manually - Trigger Flood Attack (creates 5 bot accounts with posts) - Show / Hide the join QR code - View raw database tables (users, posts, votes, reports, keys) - **WHAT THE PLATFORM SEES** — surveillance dashboard (scroll to bottom of admin panel): - *Deanonymization table*: maps every session label (Anon #N) to real username, tier, post count, and net score - *Social graph*: all handshake pairs with CONFIRMED / PENDING status - *Behavioral correlations*: who voted for whom and who reported whom, cross-referenced with confirmed friendships — project mid-session for maximum pedagogical impact --- ## Stopping the Server `Ctrl+C` in the Termux terminal. The in-memory database is destroyed immediately. There is no persistent storage — every session starts clean. --- ## Troubleshooting ### Server prints `127.0.0.1` instead of the hotspot IP **Important:** `127.0.0.1` is the loopback address — it only works in the browser on the server device itself. Participants on other devices will get "connection refused". Flask is still listening on all interfaces (`0.0.0.0`), so the server is reachable — you just need the correct IP. **Step 1:** Enable the mobile hotspot *before* running `python3 meshagora.py`, then restart. The hotspot interface only appears after the hotspot is on. **Step 2:** If still wrong, check all interfaces manually: ``` ifconfig | grep inet ``` Look for an address like `192.168.43.1` under `wlan0` — that's the hotspot gateway. Ignore `127.0.0.1` (loopback) and `10.x.x.x` under `rmnet` (mobile data). Note: `ip addr` fails in Termux with "cannot bind netlink socket: permission denied" — always use `ifconfig` instead. **Step 3:** Navigate to `http://[correct-ip]:5000/join` directly and distribute that URL to participants. **Samsung A-series:** The A25 hotspot is typically `192.168.43.1` on `wlan0`. If the banner's "Join URL" shows a different address, check the "Also try" lines for the `192.168.43.1` entry. --- ### `ModuleNotFoundError: No module named 'qrcode'` ``` pip install "qrcode[pil]" ``` If it installs but the error persists: ``` python3 -m pip install "qrcode[pil]" ``` The server runs without qrcode — `/qr` returns a 404. Participants can type the join URL directly. --- ### `ModuleNotFoundError: No module named 'flask'` ``` pip install flask ``` --- ### `ifconfig` command not found ``` pkg install net-tools ``` This is required for hotspot IP detection in Termux. Without it, the banner will fall back to `127.0.0.1`. --- ### Port 5000 already in use Common on macOS (AirPlay Receiver uses 5000). **Option A:** Kill the other process: ``` lsof -i :5000 kill [PID] ``` **Option B:** Change the port at the bottom of `meshagora.py`: ```python app.run(host='0.0.0.0', port=5001, debug=False, threaded=False) ``` Update the join URL accordingly. --- ### Participants can't reach the server 1. Confirm participants are connected to the *hotspot WiFi*, not their mobile data or a different network. 2. Confirm the IP in the banner matches `ifconfig | grep inet` output for the `wlan0` interface. 3. Confirm port 5000 is not blocked by a firewall. On Termux this is rarely an issue on a local hotspot. 4. Try navigating to the URL from the server device's own browser first to confirm the server is responding. --- ### Android kills the server mid-session (Termux background kill) Android aggressively kills background processes to save battery. **Prevention:** - In Android Settings → Apps → Termux → Battery → set to "Unrestricted" (wording varies by device). - Keep Termux in the foreground with the screen on, or acquire a wakelock: ``` termux-wake-lock ``` (Requires the Termux:API app from F-Droid.) - Keep the server device plugged in to power. If the server is killed, all session data is lost. Restart with `python3 meshagora.py` — all keys rotate, all users must rejoin. --- ### Default Post Key stopped working for everyone A user was restricted (by admin action or by 51% community reports). The Default Post Key rotates silently on every restriction. Check the Admin Panel for the new key and distribute it. --- ### Emoji picker doesn't appear / looks broken The emoji picker is rendered as inline HTML buttons with basic CSS. No JavaScript framework required. - If buttons appear but emoji don't render: the device font doesn't support those codepoints. This is rare on Android 7.0+ but possible on stripped-down browsers. Participants can type emoji directly into the visible input field. - If the grid looks misaligned: the scroll container (`max-height: 160px; overflow-y: auto`) is intentional. Scroll within the picker to see all emoji. --- ### Post fails with "Post key incorrect." for a RESTRICTED user RESTRICTED users require an admin co-sign. The admin must communicate the Admin Post Key directly to the restricted user for them to post. This is by design — it represents supervised posting access. --- ### Handshake says "One or both keys are incorrect." - Both participants must submit from their own accounts (you cannot complete both sides from one account). - Emoji must match exactly — the picker submits codepoints, not descriptions. - Try clearing both fields and reselecting. The CLEAR button resets the hidden input. - Verify both participants have submitted independently. --- ## Testing Checklist (Pre-Session) - [ ] Hotspot enabled before starting server — correct IP appears in banner - [ ] `/qr` loads a scannable QR code from the server device - [ ] Join as User 1 from a phone — "Anon #1" assigned, Default Post Key shown on join confirmation - [ ] Join as User 2 from a second device or incognito tab — "Anon #2" assigned - [ ] Post from User 1 with correct Default Post Key — appears in feed - [ ] Post from User 1 with wrong key — "Post key incorrect." error - [ ] Vote from User 2 — score updates - [ ] Report from User 2 — spoiler overlay appears, User 1 sees notification banner - [ ] Admin panel accessible at `/admin` with 4-emoji Admin Post Key - [ ] Admin restricts User 1 — Default Post Key rotates (new key visible in admin panel) - [ ] User 1 post fails with old key, succeeds with new key (or admin co-sign) - [ ] Handshake between User 1 and User 2 — confirmed, username appears on posts for the friend - [ ] Friends-only toggle shows only friend posts - [ ] Profile notes edit blocked without Profile Key, succeeds with correct key - [ ] Hide QR via admin → `/qr` returns 404 - [ ] Flood Attack → 5 bot posts appear in feed - [ ] Scroll to "WHAT THE PLATFORM SEES" in admin panel — all three panels render (deanonymization, social graph, behavioral correlations) - [ ] Confirm panels are empty (no crash) on a fresh session with no posts/votes/reports