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_info_handler(struct sip *sip, const struct sip_msg *msg, void *arg) { struct call *call = arg; if (msg_ctype_cmp(&msg->ctyp, "application", "dtmf-relay")) { struct pl body, sig, dur; int err; pl_set_mbuf(&body, msg->mb); err = re_regex(body.p, body.l, "Signal=[0-9]+", &sig); err |= re_regex(body.p, body.l, "Duration=[0-9]+", &dur); if (err) { (void)sip_reply(sip, msg, 400, "Bad Request"); } else { char s = pl_u32(&sig); uint32_t duration = pl_u32(&dur); if (s == 10) s = '*'; else if (s == 11) s = '#'; else s += '0'; info("received DTMF: '%c' (duration=%r)\n", s, &dur); (void)sip_reply(sip, msg, 200, "OK"); if (call->dtmfh) { tmr_start(&call->tmr_dtmf, duration, dtmfend_handler, call); call->dtmfh(call, s, call->arg); } } } #ifdef USE_VIDEO else if (msg_ctype_cmp(&msg->ctyp, "application", "media_control+xml")) { call_handle_info_req(call, msg); (void)sip_reply(sip, msg, 200, "OK"); } #endif else { (void)sip_reply(sip, msg, 488, "Not Acceptable Here"); } }
static void handle_message(struct ua *ua, const struct sip_msg *msg) { static const char ctype_text[] = "text/plain"; struct pl ctype_pl = {ctype_text, sizeof(ctype_text)-1}; (void)ua; if (msg_ctype_cmp(&msg->ctyp, "text", "plain") && recvh) { recvh(&msg->from.auri, &ctype_pl, msg->mb, recvarg); (void)sip_reply(uag_sip(), msg, 200, "OK"); } else { (void)sip_replyf(uag_sip(), msg, 415, "Unsupported Media Type", "Accept: %s\r\n" "Content-Length: 0\r\n" "\r\n", ctype_text); } }
static int sipsess_answer_handler(const struct sip_msg *msg, void *arg) { struct call *call = arg; int err; MAGIC_CHECK(call); if (msg_ctype_cmp(&msg->ctyp, "multipart", "mixed")) (void)sdp_decode_multipart(&msg->ctyp.params, msg->mb); err = sdp_decode(call->sdp, msg->mb, false); if (err) { warning("call: could not decode SDP answer: %m\n", err); return err; } err = update_media(call); if (err) return err; return 0; }