The CodeB SIP bridge sits between the WebRTC half (Opus over SRTP-DTLS) and the SIP half (G.711 over plain UDP), transcoding on the fly. Your SIP trunk credentials, fraud controls, and call detail records all stay on your own Windows host — CodeB never sees or routes your PSTN traffic.
Signaling / controlRTP media (transcoded at the bridge)
Browser, signal.ashx, SIP bridge, trunk · CodeB Webphone + SIP softphone share the same bridge
Browser
01 / WebRTC half
SRTP-DTLS Opus to the bridge
The browser opens a regular WebRTC PeerConnection to the SIP bridge. Audio rides on Opus at 48 kHz inside SRTP-over-DTLS. The connection is identical to a browser-to-browser CodeB meeting — the bridge is just the “other peer”.
Bridge
02 / Transcoding
Opus ↔ G.711, in-process
The SIP bridge is a Windows Service built on SIPSorcery. It decodes Opus, resamples 48 kHz ↔ 8 kHz, then encodes µ-law or A-law for the SIP side. The same process owns the SIP UDP listener (default port 5060) and the public-listener channel for inbound calls.
SIP side
03 / Plain SIP/RTP
Your trunk, your numbers
Outbound to the PSTN goes over SIP INVITE against your registered trunk(s). Inbound DIDs land on the same trunk. RTP between bridge and trunk is plain UDP G.711 — the SIP-side cipher posture is whatever your carrier supports.
What you operate vs. what we operate
CodeB Conference ships the bridge as part of the install. You operate the SIP trunk — we never see, route, or carry your PSTN traffic. The bridge connects to your trunk credentials, on your Windows host, behind your firewall:
SIP REGISTER credentials live in App_Data/<tenant>/appsettings.json on your IIS box.
CDRs (call detail records) are written to App_Data/<tenant>/cdr/ and surfaced on the admin cdr.html page — never sent anywhere off the host.
Dial logs, inbound logs, and trunk registration logs all stay on disk on your machine.
Fraud + abuse controls
The bridge enforces three gates before any PSTN egress:
Whitelist — an explicit list of dial-able numbers per tenant. Unknown destinations are refused with 403 not-in-whitelist at admit-time.
FraudGuard — per-user / per-trunk / global counters with a sliding-window cap. Stops a runaway script from emptying a trunk credit.
Route rules — country-aware allow-list (e.g. EU-only) plus per-trunk priority and concurrency limits.
Inbound calls get the symmetric treatment: a per-source-IP rate limit on the public SIP listener, optional REGISTER-required mode (default on), and SIP Digest authentication against the same credential store as the OIDC IdP — one credential, three services.
Inbound call paths
A call coming the other way — an external SIP phone calling a CodeB number — takes one of three branches inside the bridge:
Rings the CodeB Webphone — the signed-in CodeB Webphone PWA gets a ring frame over its WebSocket. Accept → the bridge fan-outs INVITE to any registered SIP softphone (parallel-fork).
Hits a virtual number — the dial-pattern matches an AI receptionist rule; the call goes to the virtual-agent path instead.
Public-listener URI — r_<room>@phone.codeb.io drops a SIP caller straight into a WebRTC room; user@phone.codeb.io rings that user’s registered softphones.
What the server sees vs. doesn’t
The signal.ashx WebSocket only carries control frames (dial requests, ring frames, accept/reject). Media never traverses signal.ashx. The bridge is the only piece that ever holds decrypted PCM samples in memory — for the milliseconds it takes to transcode and forward. Nothing is buffered to disk unless you have SaveTranscripts turned on for an AI receptionist rule (and even then only that one vnum’s text is persisted, never raw audio).