Skip to main content

serve

Function serve 

Source
pub async fn serve(
    call: &mut Call,
    incoming: &mut Receiver<Incoming>,
) -> Result<()>
Expand description

Drive a call until it ends, honouring its session timer.

The loop a call needs is not just “read the next message”: a session timer is a deadline, and a call that only ever wakes on incoming traffic can never notice that no traffic has arrived. This is that loop, written once so that the RFC 4028 half of it is not something every caller has to remember.

Returns when the far end hangs up, or Error::SessionExpired when it stops answering.

§One call, or one of many

This is the one-call convenience over Dispatcher (story C-4), and the receiver it takes is what makes it both things at once. Handed the endpoint’s own Receiver<Incoming> it is the single-call program it has always been; handed an inbox a dispatcher routed, it drives one call of any number on the same endpoint. There is no second loop for the many-call case, which is the point — a hand-rolled demultiplexer beside this one is a fresh chance to drop an ACK.

The one-call form claims the whole endpoint, so it is right only when this is the only call on it. Anything else arriving there is not this call’s, and is answered as such below.

§Nothing is discarded

A request Call::handle does not claim is answered, not dropped: 405 with Allow when it belongs to this dialog but names a method this call does not implement (RFC 3261 §8.2.1), 481 when it names a dialog that is not this one (§12.2.2), 486 for a second INVITE arriving where one call is being served (§21.4.24), and nothing at all for an ACK, which SIP has no response to. This used to be a silent drop, and it is the call-layer twin of what T-19 removed at the transport layer.