static void sipsess_progr_handler(const struct sip_msg *msg, void *arg) { struct call *call = arg; bool media; MAGIC_CHECK(call); info("call: SIP Progress: %u %r (%r/%r)\n", msg->scode, &msg->reason, &msg->ctyp.type, &msg->ctyp.subtype); if (msg->scode <= 100) return; /* check for 18x and content-type * * 1. start media-stream if application/sdp * 2. play local ringback tone if not * * we must also handle changes to/from 180 and 183, * so we reset the media-stream/ringback each time. */ if (msg_ctype_cmp(&msg->ctyp, "application", "sdp") && mbuf_get_left(msg->mb) && !sdp_decode(call->sdp, msg->mb, false)) { media = true; } else if (msg_ctype_cmp(&msg->ctyp, "multipart", "mixed") && !sdp_decode_multipart(&msg->ctyp.params, msg->mb) && !sdp_decode(call->sdp, msg->mb, false)) { media = true; } else media = false; switch (msg->scode) { case 180: set_state(call, STATE_RINGING); break; case 183: set_state(call, STATE_EARLY); break; } if (media) call_event_handler(call, CALL_EVENT_PROGRESS, call->peer_uri); else call_event_handler(call, CALL_EVENT_RINGING, call->peer_uri); call_stream_stop(call); if (media) call_stream_start(call, false); }
static void sipsess_estab_handler(const struct sip_msg *msg, void *arg) { struct call *call = arg; MAGIC_CHECK(call); (void)msg; if (call->state == STATE_ESTABLISHED) return; set_state(call, STATE_ESTABLISHED); call_event_handler(call, CALL_EVENT_ESTABLISHED, call->peer_uri); call_stream_start(call, true); /* the transferor will hangup this call */ if (call->not) { (void)call_notify_sipfrag(call, 200, "OK"); } }
int call_progress(struct call *call) { struct mbuf *desc; int err; if (!call) return EINVAL; err = call_sdp_get(call, &desc, false); if (err) return err; err = sipsess_progress(call->sess, 183, "Session Progress", desc, "Allow: %s\r\n", uag_allowed_methods()); if (!err) call_stream_start(call, false); mem_deref(desc); return 0; }