Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Agents

Constructor

agent(name: string, config: map)

Returns Agent

Connect a headless baresip agent and return a handle.

Config optionsagent(name, #{ … }):

FieldTypeDescription
usernamestring · requiredSIP user (registration / auth)
domainstring · requiredSIP domain / registrar
passwordstringauth password
display_namestringcaller display name
transportstringudp (default), tcp or tls
auth_userstringauth user, if it differs from username
outboundstringoutbound proxy URI
stun_serverstringSTUN server, e.g. stun:host:port
media_encstringmedia encryption, e.g. srtp, zrtp, dtls_srtp
regintintre-registration interval (seconds); 0 disables
mwiboolsubscribe to message-waiting indication
dtmf_modestring"info" for reliable headless DTMF (SIP INFO)
headersmapextra SIP headers on the INVITE, e.g. #{ "X-Foo": "bar" }; a value may be an array for a repeated header, e.g. #{ "X-Foo": ["a", "b"] }
deflect_tostringdeflect inbound calls with a 302 to this URI/number (toggle at runtime with deflect()/stop_deflect())
metadatamapfree-form data carried on the agent and read back as agent.metadata (e.g. #{ role: "caller" }); not used for SIP

Example

let a = agent("A", #{
    username: env("A_USER"),
    domain: env("SIP_DOMAIN"),
    password: env("A_PASS"),
});

Methods

agent.abort_transfer()

Receiver Agent

Abort the pending attended transfer.

agent.accept()

Receiver Agent

Answer the agent’s incoming call.

Example

await_until(|| assert(b.state).equals(State::Ringing), "15s");
b.accept();

agent.attended_transfer(target: Agent)

Receiver Agent · Takes Agent

Start an attended transfer: place a consultation call to another agent. Complete it with complete_transfer() once that call is established.

Example

callee.attended_transfer(target);   // consult `target`
await_until(|| assert(target.state).equals(State::Established));
callee.complete_transfer();         // connect caller and target

agent.attended_transfer(target: string)

Receiver Agent

Start an attended transfer to a literal URI or bare number.

agent.complete_transfer()

Receiver Agent

Complete the pending attended transfer (REFER with Replaces).

agent.deflect(target: Agent)

Receiver Agent · Takes Agent

Deflect inbound calls with a 302 Moved Temporarily to another agent’s AOR (a Diversion header names the deflecting agent). Arm it before the caller dials; stays active until stop_deflect().

Example

callee.deflect(target);     // future calls to `callee` go to `target`
caller.dial(callee);
await_until(|| assert(target.state).equals(State::Ringing), "15s");

agent.deflect(target: string)

Receiver Agent

Deflect inbound calls (302) to a literal URI or bare number/extension.

agent.dial(target: Agent)

Receiver Agent · Takes Agent

Dial another agent at its AOR.

Example

a.dial(b);                 // dial agent B at its AOR
a.dial("+49301234567");    // …or a number/URI in A's domain
await_until(|| assert(b.state).equals(State::Ringing), "15s");

agent.dial(target: string)

Receiver Agent

Dial a literal SIP URI, or a bare number/extension in the agent’s own domain.

agent.dtmf(digits: string)

Receiver Agent

Send DTMF tones (characters 0-9, *, #, A-D) back-to-back.

Example

a.dtmf("123#");

agent.dtmf(digits: string, gap: string)

Receiver Agent

Send DTMF tones with a pause between digits.

Example

a.dtmf("123#", "200ms");

agent.hangup()

Receiver Agent

Hang up the agent’s active call.

Example

a.hangup();
await_until(|| assert(a.state).equals(State::Idle), "10s");

agent.header(name: string)

Receiver Agent · Returns string?

Value of a header on a received INVITE (string), or () if absent.

agent.headers()

Receiver Agent · Returns map

All received INVITE headers as a map (name → value); duplicates collapse, use header(name) for a specific one.

agent.hold()

Receiver Agent

Put the active call on hold.

agent.info()

Receiver Agent · Returns map

A map of the agent’s current state: name, aor, registered, state, reason, status_code, calls. Handy to print(...) or assert on.

agent.mute()

Receiver Agent

Toggle mute on the active call.

Example

a.mute(); // mute; call again to unmute

agent.register()

Receiver Agent

(Re-)register the agent’s account.

Example

a.register();
await_until(|| assert(a.registered).is_true(), "10s");

agent.respond_incoming(status: int, reason: string)

Receiver Agent

Answer inbound INVITEs with a custom SIP response (status + reason) instead of accepting — e.g. callee.respond_incoming(486, "Busy Here"). Arm before the caller dials; clear with stop_deflect().

agent.respond_incoming(status: int, reason: string, headers: map)

Receiver Agent

Custom response with extra headers, e.g. callee.respond_incoming(302, "Moved Temporarily", #{ "Contact": "<sip:bob@example.com>" }). Header values must not contain CR/LF.

agent.resume()

Receiver Agent

Resume a held call.

agent.send_audio(source: AudioSpec)

Receiver Agent · Takes AudioSpec

Switch the agent’s active-call audio source: tone(Hz), file(path) or silent().

Example

a.send_audio(tone(440));         // play a 440 Hz tone
a.send_audio(file("prompt.wav"));

agent.stop_deflect()

Receiver Agent

Stop deflecting / clear any armed response — inbound calls are accepted again.

agent.to_json()

Receiver Agent · Returns string

The agent’s current state as a JSON string (for log(...)/debugging).

agent.transfer(target: Agent)

Receiver Agent · Takes Agent

Blind-transfer (REFER) the active call to another agent’s AOR.

Example

callee.transfer(target); // hand the caller off to `target`

agent.transfer(target: string)

Receiver Agent

Blind-transfer (REFER) the active call to a literal URI or bare number.

agent.verify_audio(freq: int, within: string)

Receiver Agent

Assert the agent is receiving a tone at freq Hz within the window (Goertzel).

Example

a.send_audio(tone(440));
b.verify_audio(440, "5s"); // b hears A's 440 Hz tone

agent.verify_audio_connection(b: Agent)

Receiver Agent · Takes Agent

Assert two-way audio between two agents (a→b then b→a) at 1000 Hz.

Example

caller.verify_audio_connection(callee);

Fields

agent.metadata

Receiver Agent · Returns map

Free-form metadata attached at agent(...) via the metadata config field, e.g. caller.metadata.role. Empty map if none was given.

agent.peer

Receiver Agent · Returns Peer

The current call’s remote party (the caller for an incoming call); read peer.uri / peer.number / peer.name (each () if there’s no call).

agent.quality

Receiver Agent · Returns CallQuality

RTP media quality of the active call (or the last call’s snapshot); read quality.mos / .rtt / .jitter / .packet_loss (each () until the first RTCP report, ~5s into a call).

Example

await_until(|| assert(caller.quality.mos).is_present(), "10s");
assert(caller.quality.mos).at_least(4.0);

agent.reason

Receiver Agent · Returns string?

The last closed call’s reason (string), or () if none yet.

agent.received_dtmf

Receiver Agent · Returns string

DTMF digits received on the active/last call, in order (e.g. "1234#"); empty until any arrive — poll with await_until.

Example

caller.dtmf("1234#");
await_until(|| assert(callee.received_dtmf).equals("1234#"), "5s");

agent.registered

Receiver Agent · Returns bool

Whether the agent’s account is currently registered.

agent.state

Receiver Agent · Returns CallState

The agent’s current call phase: Idle, Ringing or Established.

agent.status_code

Receiver Agent · Returns int?

SIP status code from the last closed call’s reason (int, e.g. 603), or () if the reason isn’t a SIP response (local hangup, reset, …).