Multi-line concurrency + web admin UI#28
Open
nicolasumaras wants to merge 1 commit into
Open
Conversation
Lifts SIPfax from single-session to N concurrent modem calls (configurable,
hot-changeable cap) fronted by a FreePBX PJSIP trunk, plus a Basic-auth web
admin UI to manage users, the cap, and view live lines.
- Multi-session core: SingleSessionManager -> MultiSessionManager (Map keyed by
Call-ID, mutable cap). Each call is a Line (src/line.js) owning its own RTP
port (RtpPortPool), modem process, and pppd. One SIP socket multiplexes by
Call-ID; per-call RTP sockets need no demux.
- Config layer (src/config.js): JSON config file (SIPFAX_CONFIG_FILE) seeded
from the existing env vars; hot-applies user/cap changes live and flags
structural changes (ports, CIDR) needsRestart; atomic 0600 persistence.
- Web admin UI (src/operator.js + public/admin.html): HTTP Basic auth on
/admin*, a vanilla no-build page + JSON API for users (add/remove), the cap,
live sessions, and the FreePBX trunk snippet (Max Channels = cap).
- PPP: render ALL configured users to {chap,pap}-secrets (was a per-call
overwrite that wiped the shared file on teardown and broke concurrent calls);
add PppCredentialStore.removeUser.
- index.js builds a per-call modem factory (unique tty link per call) and wires
config hot-apply into the live server.
Tests: 46 pass (cap accept/reject, RtpPortPool, config seed/redact/persist/
hot-apply, credential CRUD, admin Basic-auth + CRUD). Smoke-tested live on the
VM: boots multi-line, 401/200 auth, persisted user add, trunk snippet.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #27 (slmodem V.34 engine). Lifts SIPfax from single-session to N concurrent modem lines (configurable, hot-changeable cap) behind a FreePBX PJSIP trunk, plus a Basic-auth web admin UI.
Core
SingleSessionManager→MultiSessionManager(Map by Call-ID, mutable cap). Each call is aLine(src/line.js) owning its own RTP port (RtpPortPool), modem process, and pppd. One SIP socket multiplexes by Call-ID; per-call RTP sockets need no demux.src/config.js— JSON config file (SIPFAX_CONFIG_FILE) seeded from the existing env vars; hot-applies user/cap changes live, flags structural changes (ports, CIDR) needs-restart; atomic 0600 persistence.src/operator.js+public/admin.html) — HTTP Basic auth on/admin*, vanilla no-build page + JSON API: users (add/remove), cap, live lines, FreePBX trunk snippet (Max Channels = cap).{chap,pap}-secrets(was a per-call overwrite that wiped the shared file on teardown and broke concurrent calls);PppCredentialStore.removeUser.Tests
46 pass — cap accept/reject,
RtpPortPool, config seed/redact/persist/hot-apply, credential CRUD, admin Basic-auth + CRUD. Smoke-tested live on the VM (boot, 401/200 auth, persisted user add, trunk snippet).🤖 Generated with Claude Code