Per-tenant control
Writes Sip:Ice:Mode and Sip:Ice:AdvertiseTurnRelay to this tenant’s App_Data/<tenant>/appsettings.json via the rolling-50 backup. Hot-reloaded by the bridge — no service restart needed. When the per-tenant value is unset (inherit) the bridge falls back to the global Sip:Ice:Mode in sipbridge/appsettings.json (operator-only).
What this is
The bridge implements ICE-Lite (RFC 8445 sec 2.7) on the SIP media plane. When enabled per tenant, the bridge advertises ICE attributes in its SDP answers and responds to STUN BINDING connectivity checks on the RTP socket. Modern hardphones and softphones that speak full ICE on their side can then negotiate a working media path through NAT without phone-side STUN configuration.
Phones that benefit
ICE-Lite on the bridge is useful when the phone speaks full ICE (RFC 8445). Tested / known-compatible:
- Modern Yealink T5x firmware (T54W, T57W) with ICE enabled in account settings
- Polycom VVX 250 / 350 / 450 with recent firmware
- Cisco IP Phone 7800 / 8800 series
- Sangoma P-series (P310, P315, P320, P325, P330, P370)
- Snom D-series (D717, D785) with ICE enabled
- Pjsip-based softphones (Bria, Linphone with ICE on, Acrobits)
- Browser SIP clients via sip.js / JsSIP
Phones that do not speak ICE (Sangoma S-series with V2.0.4.x firmware, FRITZ!Fon, very old hardware) won’t benefit from ICE-Lite. For those, configure phone-side STUN pointing at the bridge’s TURN service (phone.aloaha.com:3478) if the phone UI exposes that setting.
Webhook events
The bridge fires call.ice.connected via the webhook system on first successful USE-CANDIDATE lock for a call. Payload:
{
"event": "call.ice.connected",
"callId": "ar-...",
"selectedPeerIp": "195.158.111.88",
"selectedPeerPort": 12114,
"checksReceived": 3,
"checksAccepted": 3,
"checksRejected": 0
}
Use this for SLA dashboards or "first audio path proven" UX. See webhooks-admin to enable / disable.
What’s in the bridge log when ICE is working
[ar-xxx] ICE-Lite: registered state hostEp=68.221.29.149:30150 ufrag=ab12cd34 mode=lite-optional [ar-xxx] ICE-Lite: STUN responder live on RTP socket [ice-lite] BINDING success for call ar-xxx: XOR-MAPPED=195.158.111.88:12114 accepted=1 useCandidate=False [ice-lite] BINDING success for call ar-xxx: XOR-MAPPED=195.158.111.88:12114 accepted=2 useCandidate=True [ice-lite] USE-CANDIDATE: selected pair for call ar-xxx -> 195.158.111.88:12114 [ar-xxx] ICE-Lite: applied selected pair -> RTP=195.158.111.88:12114 RTCP=195.158.111.88:12115
Operational limits to know
- ICE-Lite is wired across all four bridge call paths: virtual-number Voice-AI calls, softphone-to-trunk and direct-dial bridging, and inbound phone-to-office bridging. Reactive symmetric-RTP relearning still runs as the second-line corrector for non-ICE clients.
- TURN-relay candidates are advertised when
Sip:Ice:AdvertiseTurnRelay=trueAND TURN external IP is configured. SIP phones must auth-allocate against TURN themselves — bridge does not embed credentials in SDP. - No fallback if ICE connectivity checks fail. The existing reactive symmetric-RTP relearning still runs as a second-line corrector on first inbound RTP packet.