Skip to content
Germán Luis Aracil Boned edited this page Jul 18, 2026 · 33 revisions

GABPBX Wiki

GABPBX is a GPLv2 open source PBX based on the Asterisk architecture and maintained as the Germán Aracil Boned PBX project.

This wiki documents GABPBX as a system: architecture, modules, configuration, operation and implementation notes taken from the source tree.

The current release is GABPBX 1.5.17. It completes chan_sofia as a broad, production-grade, drop-in replacement for chan_sip, and delivers reliable two-way WebRTC media — DTLS-SRTP, an ICE-lite STUN responder, rtcp-mux, BUNDLE and RTCP keyframe feedback — so a browser can register, call, be called, hold and resume over secure WebSocket with audio and video, no pjproject and no libnice in the tree. 1.5.0 adds video bridging between a legacy SIP video phone and a WebRTC leg (H.264 passthrough), RFC 3264 o= version stickiness, and DTMF logging.

The headline: chan_sofia

A modern SIP channel driver built on the Sofia-SIP NUA stack — specifically our own garacil/sofia-sip fork, tag v2.0.4, a warning-clean build of Sofia-SIP 2.0.4 on GCC 14 and OpenSSL 3 (no behavior or ABI change; see Build-and-Installation). Drop-in for chan_sip (same SIP channel, sip show … CLI, SIPpeers AMI, sippeers realtime), with capabilities chan_sip never had:

  • Registration: SIP Outbound (RFC 5626), Path (RFC 3327), Service-Route (RFC 3608), GRUU.
  • Presence/voicemail: outbound PUBLISH (RFC 3903), generic outbound SUBSCRIBE, an outbound MWI watcher, solicited and unsolicited MWI, presence/BLF dialog-info.
  • Signaling: PRACK/100rel (RFC 3262), in-dialog UPDATE (RFC 3311), Q.850 Reason (RFC 3326), REFER transfer (blind and attended), out-of-dialog MESSAGE.
  • Media: SRTP/SDES (RFC 4568), DTLS-SRTP (RFC 5763/5764), WebRTC audio and two-way video, Opus passthrough, T.38 fax with a state machine.
  • Security: mutual TLS, TLS hardening, SHA-256 digest auth, a local anti-abuse SIP blacklist.
  • Diagnostics: per-call SIP history with verbose call analysis, plus a richer sip … CLI.

Start at Chan-Sofia, then Features for the full catalogue, WebRTC for the browser story, Migrating-from-chan_sip for the swap, and Security for the hardening posture.

What is new in 1.5.17

Restores a faithful ${HANGUPCAUSE} after a bridged call ends, fixing a carrier-failover double-dial / double-billing bug. No configuration change.

  • Symptom. A dialplan that dials a carrier and ends its retry loop on $[${HANGUPCAUSE}=16] (16 = normal clearing = the call was answered) re-dialed the next carrier even after a call that connected and completed normally — a second call, and a second bill, for every answered one — whenever the called party was the side that hung up.
  • Root cause. When the callee ends an answered, bridged call, only the leaving channel carries its own hangup cause; the surviving caller keeps whatever it had, usually 0. apps/app_dial.c copies the dialed party's cause to the caller only inside the if (!ast_check_hangup(peer)) guard — i.e. only when the caller hangs up — so on a callee hangup that copy was skipped and ${HANGUPCAUSE} (the channel's own cause) stayed 0, which the dialplan read as "not answered".
  • Fix. ast_bridge_call() now propagates the hung-up party's hangup cause to the surviving bridged channel when the bridge ends, mirroring modern Asterisk's bridging framework (bridge_dissolvechannel_set_cause): an existing positive cause is preserved, a zero/unknown real hangup is normalized to NORMAL_CLEARING (16), and a feature/time-limit return with no hung side is a no-op. chan_sip already set the caller's cause on answer and chan_sofia did not, so this restores chan_sip parity: ${HANGUPCAUSE} is now 16 after any normally-answered call regardless of which side hangs up, while busy / no-answer / congestion / reject — which never reach the bridge — are unchanged and still fail over. Validated live across chan_sofia, chan_sip and Local channels.

What is new in 1.5.16

Makes chan_sofia BLF work end to end: a watcher subscribing to any configured extension now gets a live lamp — including extensions that have not registered yet — without the duplicate/stranded hints seen before. No configuration change.

  • Root cause. sofia_create_peer_hint() placed the hint with ast_context_find_or_create(), a check-then-act (read-lock lookup, unlock, write-lock insert). Under a same-name race the loser was prepended to the context list but rejected from the context hashtab (duplicate name), becoming a list-only orphan context. Hint resolution (ast_get_hintpbx_find_extensionfind_context) reads the hashtab only, so a hint on an orphan was unreachable: the SUBSCRIBE still answered 404 and orphans piled up as duplicates (core show hints showed many same-named hints, all Watchers 0, while the lookup resolved none).
  • Fix. The hint is added by context name with ast_add_extension() — it resolves the hashtab-authoritative context under the contexts lock and adds atomically, so the hint lands exactly where the presence lookup resolves it and survives a dialplan reload. A subscribecontext is often a BLF-only namespace the dialplan does not define, so the context is created once only when ast_context_find() shows it genuinely absent — an already-defined context (e.g. default) is never re-created and so never duplicated, and a by-name add can never strand the hint on an orphan.
  • Automatic hints. Hints are created at peer build (config load, realtime register/lookup) and, for a configured peer whose hint does not exist yet, on demand when a watcher subscribes: the presence SUBSCRIBE builds the target and creates its hint synchronously, then re-checks, so a BLF SUBSCRIBE to any configured target is answered 202 instead of 404. The hint context resolves subscribecontext first, else the peer context; create, remove and lookup all use that resolution, and the peer string fields are snapshotted under the peer lock before the dialplan operations.

What is new in 1.5.15

Two chan_sofia presence fixes that made watched-extension (BLF) lamps go stale and never settle into a full mesh. No configuration change; no behavior change outside the broken presence paths.

  • BLF subscriptions no longer die at their first refresh. The presence 200/202 and NOTIFYs carried the Sofia-SIP stack-default wildcard Contact (<sip:*@host>), which is not routable. A watcher adopts that Contact as the dialog remote target (RFC 3261 §12.1.1) and — because a refreshing SUBSCRIBE and a NOTIFY are target-refresh requests (RFC 6665 §3.1/§4.4.1) — refreshes in-dialog to SUBSCRIBE sip:*, which chan_sofia cannot resolve to a hint, so it answers 404 Not Found and tears the subscription down as terminated;reason=timeout. Every Event: dialog subscription therefore established and then collapsed on its first renewal, so watcher meshes were uneven and never settled. The presence responses and NOTIFYs now emit a routable Contact whose user-part is the watched extension (via the Sofia-SIP NUTAG_M_USERNAME tag), on those messages only — the stack still fills in host and port; refreshes route back and the subscription persists. MWI (Event: message-summary) was unaffected.
  • On-hold device state no longer sticks busy. The per-peer on-hold counter leaked a +1 when a call was hung up or transferred while still on hold (the resume that would decrement it never arrives), pinning SIP/<peer> ONHOLD — which outranks in-use in the device-state calculation — with zero live channels, so BLF watchers saw the extension permanently busy. The count is now released on every teardown path, tracked independently of a mid-call notifyhold reload and bounded against underflow.

What is new in 1.5.14

A diagnostics addition. No configuration or behavior change.

  • sip show version CLI. A new command reports which Sofia-SIP library chan_sofia is using: the compile-time version it was built against, the runtime version exported by the shared object actually loaded (a differing value flags a library newer or older than the headers chan_sofia was compiled against), and the resolved path of that shared object.

What is new in 1.5.13

A follow-up to the 1.5.12 audit that closes one more memory-exhaustion leak. No configuration or behavior change for a correctly-configured deployment.

  • Blacklist-drop SIP handle leak closed (DoS under attack). Under an active SIP brute-force — the exact condition the built-in IP blacklist exists to defend against — every out-of-dialog request the blacklist dropped (REGISTER, SUBSCRIBE, MESSAGE, NOTIFY, REFER, INFO, PUBLISH) leaked the fresh protocol handle the stack had created for it, along with its memory pool — and, for SUBSCRIBE, a dialog leg that is never reclaimed. Only OPTIONS was reaped on the drop path, so a sustained flood of a blacklisted source grew memory without bound precisely while the box was under attack (the anti-brute-force defense amplifying the DoS). The drop path now reaps the unbound handle for every out-of-dialog method (the same magic-guarded reap already used for OPTIONS); a bound, in-dialog handle is never touched. Verified on a live box with malloc_trim before/after: the leak grew ~5 KB per dropped request and could not be reclaimed before the fix, and returns to baseline after it.

What is new in 1.5.12

A focused security-hardening release from a full audit of chan_sofia (correctness, memory safety, exploit-class). Eight fixes; no configuration or behavior change for a correctly-configured deployment.

  • OPTIONS keep-alive handle leak closed (DoS). An out-of-dialog OPTIONS — the common registrar/proxy keep-alive — is auto-answered 200 by the stack, but the fresh handle it created was never destroyed: every ping leaked a handle and its memory pool, unbounded, remote, unauthenticated. The handler now reaps the unbound handle and no longer double-responds.
  • Inbound DataChannel receive queue bounded (DoS). A peer flooding SCTP application data over an established WebRTC DataChannel could grow the shared worker queue and heap copies without limit; a per-DataChannel in-flight cap now drops under pressure (SCTP retransmits).
  • alwaysauthreject is now a true anti-enumeration control. An unknown user got a 401 challenge while a known user with a bad password got 403, so a credentialed retry revealed which accounts exist. Unknown-user auth now runs through the same digest verifier against an internal bogus account (matching chan_sip), so the 400/401/403 result — and its timing — is identical either way.
  • Delayed authentication rejections are now transmitted. The anti-enumeration delayed 401/403 was bound to the request being processed, which does not exist in the timer that fires it, so the stack silently dropped every delayed reject; it is now bound to the saved request and reaches the wire.
  • Strict stateless-nonce parsing. A nonce with trailing bytes after its canonical form is now rejected (the validator no longer accepts a non-canonical suffix the digest/replay logic keyed on).
  • Masquerade-race use-after-free closed. Off-thread finders and AMI/log emits that read a peer channel's name or linked-call id now take the channel lock, so a concurrent masquerade/rename can no longer free that string out from under the read.
  • Malformed / out-of-dialog REFER rejected before accept. A REFER with no Refer-To or no active call was answered 202 Accepted first (orphaning a transfer subscription) then dropped; it is now rejected 400/481 before the 202.

What is new in 1.5.11

  • Local-hold offer direction (experimental, default off). chan_sofia has always answered a local hold with music-on-hold only, never telling the held peer over SIP. With [general] hold_reinvite = sendonly (or inactive), a local hold now also re-INVITEs the peer to a=sendonly (peer stops sending and hears our MOH, RFC 6337) or a=inactive, restoring a=sendrecv on UNHOLD; a rejected/unanswered hold re-INVITE rolls back. A typed re-INVITE purpose keeps directmedia, T.38 and local-hold response handling isolated from each other. Default no = prior MOH-only behavior. Shipped experimental and off by default — the enabled path is validated end to end in a controlled test; still off by default pending production soak, validate before enabling.

What is new in 1.5.10

  • Forked-call early media (experimental, default off). When a call to a peer forks to multiple registered contacts, chan_sofia keeps the caller muted until one branch answers. With the new [general] fork_early_media = yes, once the fork narrows to a single live non-WebRTC branch that sends a 180/183 with SDP, the caller hears that branch's early media (receive-only). Conservative by design: never binds while two or more branches are live, never sends media upstream before answer, no-op for WebRTC, and hands media to the winner (or restores silence) on answer/failure. Shipped experimental and off by default — the enabled path is validated end to end in a controlled test; still off by default pending production soak, validate before enabling.

What is new in 1.5.9

Q.850 signaling reaches full chan_sip parity on rejected calls.

  • Q.850 Reason on INVITE rejects. With use_q850_reason = yes, chan_sofia now stamps an RFC 3326 Reason: Q.850;cause=N;text="..." header on INVITE-rejection responses (404, 480, 484, 486, 488, 503, and the in-dialog re-INVITE / UPDATE / T.38 488 rejects), not only on the BYE/CANCEL requests it already handled, so upstream proxies and billing see the real Q.850 cause behind a rejected call. The cause is taken from the channel hangup cause, or mapped from the SIP status via a port of chan_sip's hangup_sip2cause for pre-channel rejects. Gated by use_q850_reason (default no).

What is new in 1.5.8

A correctness follow-up to the audit — SDP body sizing, early-media signaling parity with chan_sip, MWI summary completeness and RTCP report handling.

  • SDP buffer headroom. A WebRTC video answer using BUNDLE with several H.264/VP8 payload types, their per-payload a=rtcp-fb lines and ICE candidates could exceed the fixed 2048-byte SDP body buffers, making the SDP builder fail closed and emit no SDP. The six response/offer SDP buffers now hold 4096 bytes, and the internal video attribute accumulators hold 2048 bytes (those can fill before the outer buffer on a rich video m-line), so a valid video answer is no longer silently dropped.
  • progressinband=no vs never. With progressinband=no, a RINGING indication now degrades to in-band ringback once a 183 Session Progress has already been sent (early media exists), matching chan_sip; previously no collapsed onto never.
  • MWI multi-class summaries. The application/simple-message-summary parser (RFC 3842) now aggregates the new/old message counts across all message classes (Voice, Fax, Pager, Multimedia, Text), each saturated, with the Messages-Waiting line as the fallback when no per-class counts are present.
  • RTCP multi-block reports. An RTCP SR/RR carrying more than one reception report block (RFC 3550) now selects the block that concerns our own SSRC for RTT/jitter/loss statistics, instead of always using the first block.

What is new in 1.5.7

A further audit-hardening batch — correctness, security, concurrency and robustness across chan_sofia, sofia_sdp, sdp_crypto, res_rtp and the RTP engine.

  • RTP codec-map concurrency. The per-instance codec payload map has no lock of its own, so installing a freshly negotiated map on the SIP/SDP thread raced the media threads reading it; every live-map install and every media-thread reader now serialize under the RTP instance lock, and the peer-to-peer bridge takes its two instance locks separately so opposite bridge directions cannot deadlock. The outbound SRTP protect+send is likewise serialized against DTLS-SRTP (re)install and RTCP transmit on the same session.
  • SRTP key hygiene. sdp_crypto never logs the local SRTP master key, zeroizes key material before free (RFC 4568 §9.1), rejects an over-long inline key instead of truncating it, and echoes the accepted crypto tag on a re-keying re-INVITE (RFC 4568 §5.1.2).
  • BUNDLE answer correctness. A WebRTC answer lists the a=group:BUNDLE mids in the offered m-line order (RFC 8843 §7.3.1) instead of a fixed audio-first order, and the mid/group buffers are sized end to end for standards-legal long mids (no dropped group line, no truncated mid).
  • T.38 and video re-offers. An image-only T.38 re-INVITE is answered with m=image only (no phantom m=audio, RFC 3264 §6); a later re-INVITE on a leg that offered WebRTC video keeps offering m=video (the emit is gated on the live video capability); and a forked call applies its winning branch's negotiated audio codec to the answered channel instead of relying on transcoding.
  • Robustness. A malformed trailing RTCP sub-packet no longer discards a keyframe request latched earlier in the same compound packet; the native bridge takes the second channel's video/text remote-address baselines from the video/text instances; a very large blacklist_ban no longer overflows into a permanent ban; a refused sip reload no longer mutates the live blacklist window; REGISTER rejects bind their final response to the request; and the per-peer lock is destroyed on teardown.

What is new in 1.5.6

An audit-hardening batch across chan_sofia, sdp_crypto, sofia_t38 and res_rtp — security, protocol correctness and concurrency.

  • SRTP key confidentiality. sdp_crypto no longer echoes the caller-controlled a=crypto attribute — which carries the inline master key+salt (RFC 4568 §6.1) — at log level; the "lifetime unsupported" and malformed-line paths now log only non-secret fields (RFC 4568 §9.1).
  • Per-suite key advertised == installed. In per-suite-fresh-key mode the emitted a=crypto now advertises the same key the local SRTP policy actually installed (a single selector feeds both), so the remote no longer decrypts with the wrong key; and the "unchanged crypto" short-circuit compares suite + selected index + key (not the key bytes alone), so a suite switch (…_80…_32) with a reused key correctly re-keys.
  • RTCP concurrency. The scheduled RTCP SR/RR and the video-update PLI now serialize on the SRTCP session (they protected+sent on the same libsrtp session concurrently); T.38 parameter interpretation and the late-offer ACK SDP parse now run under the proper lock; and outbound-call paths no longer read freeable peer string fields (host/name) during a sip reload.
  • Inbound UAS hangup. An unanswered inbound INVITE is now rejected with a final response mapped from the hangup cause (chan_sip parity — 403/486/503/… instead of CANCEL), with a guard so a call already rejected by Busy()/Congestion() never emits a double final response.
  • Response binding. In-dialog UPDATE and NOTIFY responses are bound to their server transaction (NUTAG_WITH_THIS), so the 500/200 actually reaches the wire instead of being dropped and retransmitted to timeout.
  • Fork BLF. A forked call's winner now decrements the peer ringing counter on answer, so device state moves RINGING → INUSE instead of staying RINGING for the whole call.

What is new in 1.5.5

  • fromuser overrides the outbound From user (chan_sip parity). A peer's fromuser was only a fallback for the outbound From URI user — used solely when no caller-ID resolved. chan_sip treats it as an override that wins over the resolved caller-ID (chan_sip.c:12900-12901), so a peer with no callerid whose channel carried the inbound SIP username emitted that username in the outbound From instead of the configured fromuser (which some carriers reject). fromuser, when set, now overrides the From URI user in both allowed and restricted presentation. Only the From URI user changes — the display name, presentation, Contact, and any RPID/PAI headers are untouched (chan_sip's RPID builder never consumes fromuser). Restricted presentation now matches chan_sip exactly ("Anonymous" <sip:<fromuser>@anonymous.invalid>), and usereqphone tests the final From user so a non-numeric fromuser no longer inherits ;user=phone. Completes the empty-callerid outbound parity from 1.5.3/1.5.4.

What is new in 1.5.4

  • Outbound From never leaks the peer section name; [general] callerid default. The outbound From identity resolver used the peer/section name as a fallback when no caller-ID could be resolved (no channel/connected-line identity, no peer cid_num, no fromuser) — so an anonymous inbound call from a peer with no callerid could leak the peer's account/auth name into the From. chan_sip never does this. The peer->name fallback is removed, and a new [general] callerid sets the last-resort fallback From identity (chan_sip default_callerid parity, default gabpbx; shown in sip show settings as "Default callerid"). It is only used when nothing else resolves an identity and does not override a real caller-ID. Completes the empty-callerid parity from 1.5.3 (an inbound From still passes through unchanged when the peer callerid is unset). Also silences a pre-existing build warning — chan_sofia now compiles with zero warnings.

What is new in 1.5.3

  • Peer callerid on the outbound From (chan_sip parity) + apply_peer_callerid. A peer that authenticates with one SIP username but is configured with callerid=<number> was leaking its SIP username into the outbound From instead of presenting the configured number (which upstream proxies/SBCs may reject). Two-part fix: (1) a peer's callerid= is now split into the cid_num/cid_name fields the driver actually uses — previously a duplicate config handler shadowed the split in both the static and realtime loaders, so the configured callerid never took effect; (2) new [general] apply_peer_callerid (default yes, chan_sip parity) forces the matched peer's cid_num/cid_name/callingpres onto an inbound call when no trusted RPID/PAI was accepted, so the configured callerid appears in the outbound From. A trusted RPID/PAI still wins; shrinkcallerid is honored; apply_peer_callerid=no keeps the inbound From user (pass-through). The source of truth is the peer callerid field; a dialplan Set(CALLERID(num/name)) remains an optional later override. Applies on sip reload.

What is new in 1.5.2

  • auth_qop — chan_sip legacy no-qop MD5 digest challenge. Some legacy handsets only authenticate against chan_sip's exact 401 challenge (the RFC 2069 form Digest algorithm=MD5, realm="…", nonce="…" with no qop); against chan_sofia's RFC 2617/7616 qop="auth" form they failed the second REGISTER with 403. New [general] auth_qop (default no) emits the chan_sip legacy no-qop MD5 challenge — with auth_algorithms=md5 it is byte-for-byte chan_sip's — while auth_qop=yes restores qop="auth" with nc/cnonce replay protection. MD5 only (SHA-256 always keeps qop); applies on sip reload. ⚠️ The default no (RFC 2069) has no digest replay protection, matching chan_sip — pair it with TLS/WSS, or set auth_qop=yes where handsets allow.

What is new in 1.5.1

  • sip reload no longer falsely refused on tls_min_version. On a config with no explicit tls_min_version= line, the reload check compared the running effective default (TLS 1.2) against an empty scratch default and reported a phantom listener change, refusing every sip reload with listener config changed (tls_min_version) until a full restart. The scratch now seeds the same effective default (shared with the load path so the two cannot drift), while a genuine change such as tls_min_version=1.3 is still correctly detected as requiring a restart.

What is new in 1.5.0

  • Video between a legacy SIP video phone and a WebRTC leg. A SIP phone that offers H.264 (RTP/AVP) can now exchange two-way video with a browser leg, with no transcoding. The answer sent to the caller is narrowed to the video codec the far/bridge leg actually negotiated (RFC 3264 §6): codecs the far leg cannot produce are dropped instead of merely reordered, so the caller does not lock its video onto a payload type the peer will never send. H.264 a=fmtp (profile-level-id / packetization-mode, RFC 6184 §8.2.2) is relayed and, when the two sides cannot agree, video fails closed to audio rather than sending a stream the peer drops. The intersection is SDP-only — no channel format state is mutated mid-call — and a keyframe request crosses the bridge in both directions (SIP INFO picture_fast_update ⇄ RTCP PLI/FIR, RFC 5168/4585/5104). The INFO answer is now bound to its own transaction (NUTAG_WITH_THIS), removing a ~32-second Timer-F cut. See WebRTC.
  • SDP o= version stickiness (RFC 3264 §8). A re-offer that repeats the same session origin with an unchanged (<=) version is treated as a no-op, so a learned symmetric-RTP remote address survives an UPDATE/re-INVITE — matching chan_sip process_sdp_o and preserving audio across NAT keepalive re-offers. The ignoresdpversion option is honoured (default no).
  • DTMF logging. sip set debug dtmf on|off logs every received DTMF digit (RFC 2833/telephone-event, SIP INFO, or inband) to the CLI and the messages log, the way chan_sip did — useful when diagnosing IVR and feature-code entry. Default off. See Chan-Sofia.

What is new in 1.4.2

  • WebRTC call hold/resume works end to end. Pressing Hold on a WebRTC phone no longer tears the call down, and video resumes by itself on unhold, exactly like audio — in every combination of WebRTC and desk-phone endpoints, on either side of the call. Five fixes: the SDP answer now mirrors the offered per-media direction (RFC 3264 §6.1); answers mirror every offered m-line using the current offer/answer transaction role (RFC 3264 §6); the fork-winner handover preserves the SDP stream identity (cname/msid, RFC 7022/8830); negotiated video payload types survive renegotiation (RFC 3264 §8.3.2); and RTCP keyframe feedback (PSFB PLI/FIR, RFC 4585/5104) is implemented end to end — advertised as a=rtcp-fb, relayed across the bridge, and transmitted SRTCP-protected over the ICE-selected tuple. See WebRTC.

What is new in 1.4.1

  • WebRTC fork-winner media fix. When a call forks to an extension registered from both a browser (wss) and a desk phone (udp) and the browser answers first, the call now carries two-way audio and video (previously the winning leg's DTLS never completed because stale media descriptors starved its socket). See WebRTC.
  • Native peer-to-peer SIP text messaging. An out-of-dialog MESSAGE between two registered users is delivered to the recipient's live devices, resolved through the same auto-created hint namespace as BLF and fanned out to every registered contact (RFC 3428). New option message_autorelay (default on); the message_context dialplan route remains available as a fallback. See Features.

What is new in 1.4.0

  • Reliable WebRTC audio. The ICE media tuple is now latched on every integrity-authenticated connectivity check, not only the nominated pair, removing intermittent one-way audio and the 10–20 s startup gap and making inbound calls to a browser come up cleanly (RFC 8445 / RFC 7675). See WebRTC.
  • Bundled WebRTC video. A new option webrtc_video_bundle (per-peer and [general], default off, requires webrtc=yes) carries audio and video over a single ICE/DTLS transport with payload-type demux and the RTP MID header extension (RFC 8843 max-bundle, RFC 8285). See WebRTC.
  • Per-Contact registration. Each Contact in a REGISTER now binds, refreshes and de-registers independently with its own ;expires (RFC 3261 §10.3), and a call to a peer whose bindings have all expired returns CHANUNAVAIL instead of routing to a stale binding. See Chan-Sofia.
  • DTMF parity with chan_sip. The negotiated DTMF mode is reflected end to end: telephone-event is advertised only for RFC 2833 modes, dtmfmode=auto resolves at SDP commit with a fax-safe detector reconfigure, and inbound SIP INFO signals are parsed. See Features.
  • TLS 1.2 accepted by default. tls_min_version now defaults to TLS 1.2 (1.2 and 1.3) instead of 1.3-only, so endpoints that cap at TLS 1.2 connect. See Security.
  • Live decrypted SIP capture. sip_capture_address streams every decrypted SIP message (udp/tcp/tls/ws/wss, with SDP) as HEP to a Homer/sipcapture server, sip_capture_file writes the same to a text file, and rtp set debug ice / sip set debug fork add targeted tracers. See Operations.

What is new in 1.3.5

  • Inbound WebRTC calls now connect. A call placed to a wss-registered browser (GABPBX as the SDP offerer) comes up with two-way audio, alongside the already-working browser-originated calls. Two RFC-grounded fixes make it work: an ICE role-conflict repair (GABPBX replies 487 Role Conflict so the browser flips to controlling and nominates a pair, RFC 8445), and deferring inbound DTLS until the answer's a=fingerprint is installed instead of failing closed (RFC 5763/8842). Rejected video tears down only its own pre-armed DTLS/ICE and never drops the audio call. See WebRTC.
  • SDP/ICE diagnostics. sip set debug sdp [on|off] traces the generated offer SDP, the WebRTC offer-gate decision, the incoming answer SDP and the offerer answer-apply path — the WSS/TLS signalling already decrypted. Every Sofia: … debug line now carries a [from-user|to-user|callid] transaction tag. See Operations.

What is new in 1.1.2

  • WebRTC media is no longer roadmap. Two WSS browsers can hold a real two-way audio call, with two-way video (VP8/H.264) on top. See WebRTC.
  • Opus relays without transcoding. Three core fixes (codec selection, the 48 kHz clock rate, and the RTP smoother) let a both-Opus call pass through cleanly. See Features → Opus.
  • The full chan_sofia SIP and media catalogue is documented one feature at a time in Features.

First Chapter

  • Chan-Sofia - the Sofia-SIP based SIP channel driver and chan_sip replacement.
  • Features - the complete chan_sofia capability catalogue, one by one.
  • WebRTC - browser SIP over WSS, DTLS-SRTP, ICE-lite, audio and video.
  • Migrating-from-chan_sip - the two-line swap and what carries over.
  • Security - the security and robustness posture.

Current Chapters

Source Policy

Documentation in this wiki follows the source code first. When a behavior is uncertain, the source file and sample configuration are authoritative.

Clone this wiki locally