Skip to content
Germán Luis Aracil Boned edited this page Jul 4, 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.10. 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. 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.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 not yet validated end to end; 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