# Unit 11 — README.md ## Goal Write the main `README.md` at the project root. This is the last unit — written after all code exists. ## File - `README.md` --- ## Required Sections ### Header - Project name + one-line description - Badges (optional): Python version, license ### Architecture Diagram Copy from `design.md`: ``` ┌─────────────────────────────────────────┐ │ Server Host (srsRAN gNB) │ │ - srsRAN gNB │ │ - Open5GS Core (or free5gc) │ │ - Subscriber database │ └─────────────┬───────────────────────────┘ │ 5G NR ▼ ┌─────────────────────────────────────────┐ │ UE WiFi AP Drop │ │ (Android device or Raspberry Pi) │ │ - WiFi AP (open network) │ │ - eSIM Provisioning Server │ │ - Captive Portal │ └─────────────┬───────────────────────────┘ │ WiFi ▼ End User Devices ``` ### User Flow (numbered list) 1. User connects to open WiFi `Emergency-5G` 2. Captive portal auto-redirects to activation page 3. User taps "Activate eSIM" 4. Server generates IMSI/Ki/OPc/ICCID 5. eSIM profile downloaded to device 6. User installs profile via Settings 7. Device connects to 5G network automatically ### System Requirements **Raspberry Pi:** - Raspberry Pi 4 (4GB+ RAM) - Quectel RM500Q 5G modem (or compatible) - Raspberry Pi OS Lite 64-bit - Python 3.11+ **Android:** - Android 9+ with Termux (F-Droid) - 5G-capable device - Pre-provisioned SIM for gNB backhaul **End-user devices:** - eSIM-capable device (eUICC support) - Any OS (Android, iOS, Windows) ### Quick Start (5 commands) ```bash git clone cd esim-provisioning python3 -m venv venv && source venv/bin/activate pip install -r requirements.txt cp config.yaml.example config.yaml # edit as needed python scripts/init_db.py python -m server.app # → Server running at http://localhost:5000 ``` ### Configuration Guide Key `config.yaml` fields: | Field | Description | Example | |-------|-------------|---------| | `network.mcc` | Mobile Country Code | `"302"` | | `network.mnc` | Mobile Network Code | `"720"` | | `network.op_key` | Operator key (hex, 16 bytes) | `"63bfa..."` | | `wifi.ip` | WiFi AP IP address | `"192.168.4.1"` | | `database.path` | SQLite database path | `"/opt/.../subscribers.db"` | | `rate_limiting.window_hours` | Rate limit window | `1` | | `core.type` | Core adapter | `"open5gs"` / `"none"` | | `core.mongodb_uri` | MongoDB connection | `"mongodb://localhost:27017"` | ### Raspberry Pi Installation Reference `scripts/setup_wifi_ap.sh` for automated setup, or follow manual steps from `configs/` directory. ### Android / Termux Installation ```bash bash android/termux_setup.sh ~/esim-provisioning/start.sh ``` See `android/README.md` for detailed instructions and limitations. ### API Reference | Endpoint | Method | Description | |----------|--------|-------------| | `/activate` | GET | Captive portal page | | `/api/provision` | POST | Generate eSIM profile | | `/api/profile/` | GET | Download profile | | `/api/export` | GET | Export all subscribers (JSON) | | `/api/status` | GET | Health check | ### Troubleshooting **Profile generation fails:** ``` Check: python -c "from server.profile_generator import generate_ki; print(generate_ki().hex())" Check: OP key is 32 hex chars (16 bytes) in config.yaml ``` **Captive portal not showing:** ``` Check: nslookup google.com 192.168.4.1 → should return 192.168.4.1 Check: systemctl status dnsmasq nginx Check: iptables -t nat -L PREROUTING ``` **5G authentication fails after eSIM install:** ``` Check: IMSI/Ki/OPc in subscriber database matches what's in Open5GS Check: PLMN (MCC+MNC) matches gNB configuration Check: python scripts/sync_subscribers.py Check: Open5GS UDM/AMF logs: journalctl -u open5gs-udmd ``` **Rate limit blocking legitimate user:** ```sql -- Find and clear rate limit for a MAC: sqlite3 /path/to/subscribers.db \ "DELETE FROM subscribers WHERE mac_address='aa:bb:cc:dd:ee:ff';" ``` ### Architecture Notes - **Adapter pattern**: Adding a new core (e.g., srsRAN-CN) requires only a new class in `server/core_adapters/` - **IMSI space**: 10^10 possible MSINs per MCC+MNC — effectively unlimited for field use - **Rate limiting**: Per MAC address, 1 profile per hour window. SQLite-backed, survives restarts - **Profile format**: Phase 1 mock (JSON bytes). Phase 2: real SGP.22 via pySim for eUICC compatibility ### License MIT (or as appropriate for deployment context) --- ## Writing Notes When writing the actual README.md: - Keep it scannable — use tables, code blocks, headers - Lead with the architecture diagram - Quick Start must work in <5 minutes on a fresh Pi - Troubleshooting section is critical — include it prominently - Do not duplicate design.md — link to it for deep dives