XSIP
Stateful SIP protocol engine for the Xirsys Elixir stack.
Updated from an earlier Xirsys SIP implementation; released for public use.
Real-time voice and video over SIP needs more than parsing messages: requests
must match transactions, retransmit on UDP, form dialogs after INVITE, and
route BYE/REGISTER/OPTIONS to your application logic. XSIP is a UA-oriented
engine that handles that state machine on top of
xmedialib wire codec. You bring
transport (UDP, TCP, WebSocket framing) via XSIP.Transport. INVITE SDP
answers delegate to xsdp through
XSIP.SDP.
RFCs
- RFC 3261 -- SIP core (messages, transactions, dialogs)
- RFC 6026 -- server INVITE accepted state / Timer L
- RFC 5626 -- Outbound flow binding (minimal
ob=support) - RFC 3264 -- SDP offer/answer (via
XSIP.SDP/ xsdp) - RFC 7118 -- SIP over WebSocket (host transport concern)
Scope
xsip owns transactions, dialogs, TU dispatch, and method features on top of
xmedialib (XMediaLib.SIP codec).
I/O is bring-your-own via XSIP.Transport.
This is a UA-oriented engine for the paths listed below, not a claim of full RFC 3261 (or related) conformance.
Supported today (implemented and exercised)
| Area | Notes |
|---|---|
Typed headers + XSIP.Message | Built on XMediaLib.SIP; unit-tested round-trips |
BYO XSIP.Transport | XSIP.Transport.Mock for tests |
| INVITE / non-INVITE client and server transactions | incoming/4, respond/2, send_request/5; timers and retransmit paths in mix test |
| CANCEL matching | Matches INVITE; feature responds 487 while early |
| Non-2xx ACK absorption | Unit-tested on the INVITE server transaction |
| RFC 6026 accepted state | 2xx moves server INVITE to accepted with Timer L; covered by dialog/2xx flows, not a dedicated Timer L assertion |
| Dialogs + TU | Out-of-dialog OPTIONS, REGISTER, INVITE; in-dialog BYE |
| REGISTER Contact echo | 200 echoes request Contact(s) |
| Minimal RFC 5626 | Contactob= (or app flow_token) binds in XSIP.Outbound.Store; reconnect reuses the token |
XSIP.App callbacks | Host registrar / invite policy hooks |
| Telemetry | Transaction/dialog start-stop and incoming errors |
Reference host and SIP.js client (separate repos) exercise the wire happy paths:
OPTIONS, REGISTER (incl. unregister), INVITE/ACK/BYE, CANCEL/487, reject/486,
Outbound ob= reconnect, unknown method/405, and SIP over WebSocket (RFC 7118)
plus UDP/TCP framing in the demo.
Not claimed
- Full RFC 3261 UA or proxy compliance (digest, forking, Record-Route, merge detection, re-INVITE, overlapping transactions, and most edge cases)
- Full RFC 5626 (keepalives,
reg-id/+sip.instanceedge recovery, Path) - RFC 3262 PRACK, 3428 MESSAGE, 3515 REFER, 6665 SUBSCRIBE/NOTIFY, 3903 PUBLISH, 3326 Reason, 3327 Path, 5954 IPv6 comparison as product features (some header type stubs exist; no feature/tests)
Usage
# config :xsip, app: MyApp.SIPHandler
# Adapter after framing:
XSIP.incoming(raw, MyTransport, conn, peer)
Installation
def deps do
[
{:xsip, "~> 0.1.0"},
{:xmedialib, "~> 0.3.0"},
{:xsdp, "~> 0.1.0"}
]
end
Contact
For questions or suggestions, email experts@xirsys.com
Copyright
Copyright (c) 2013 - 2026 Jahred Love & Xirsys LLC
All rights reserved.
XSIP is licensed by Xirsys, with permission, under the Apache License Version 2.0. See LICENSE for the full license text.