fakepbx
In-process SIP server (UAS + UAC) for testing — no Docker, no external processes, no hardcoded ports.
Rust port of github.com/x-phone/fakepbx.
Usage
use ;
// Start a PBX on 127.0.0.1 with an ephemeral port.
let pbx = new;
// Program the call flow.
pbx.on_invite;
// Point your SIP UA at pbx.addr() and dial.
println!;
println!;
// The server stops automatically when `pbx` is dropped.
Supported Methods
| Method | Default Behavior | Handler |
|---|---|---|
| REGISTER | 200 OK (or digest auth) | on_register() |
| INVITE | 100 + 200 OK with SDP | on_invite() |
| BYE | 200 OK | on_bye() |
| CANCEL | 200 OK + 487 to INVITE | on_cancel() |
| ACK | — | on_ack() |
| REFER | 202 Accepted | on_refer() |
| OPTIONS | 200 OK | on_options() |
| INFO | 200 OK | on_info() |
| MESSAGE | 200 OK | on_message() |
| SUBSCRIBE | 200 OK | on_subscribe() |
Digest Authentication
let pbx = new;
// First REGISTER gets 401 with challenge, second with valid credentials gets 200.
INVITE Handlers
// Auto-answer all calls.
pbx.auto_answer;
// Auto-reject with 486 Busy.
pbx.auto_busy;
// Custom flow with early media.
pbx.on_invite;
// Wait for CANCEL (e.g. caller hangs up before answer).
pbx.on_invite;
ActiveCall (In-Dialog Actions)
pbx.on_invite;
Outbound INVITE (UAC)
// PBX initiates a call to a remote SIP UA.
let oc = pbx.send_invite
.unwrap;
// Access the sent request and received response.
assert_eq!;
// In-dialog actions work the same as ActiveCall.
oc.send_bye.unwrap;
Out-of-Dialog Requests
// Send a MESSAGE.
let code = pbx.send_message.unwrap;
assert_eq!;
// Send an OPTIONS ping.
let code = pbx.send_options.unwrap;
assert_eq!;
Request Inspection
// Count received requests.
assert_eq!;
assert_eq!;
// Wait for a BYE with timeout.
assert!;
// Inspect the last INVITE.
let inv = pbx.last_invite.unwrap;
println!;
SDP Helpers
use ;
// Minimal SDP with PCMU.
let s = sdp;
// Multiple codecs.
let s = sdp;
// With direction (hold).
let s = sdp_with_direction;
License
MIT