static void call_destructor(void *arg) { struct call *call = arg; if (call->state != STATE_IDLE) print_summary(call); call_stream_stop(call); list_unlink(&call->le); tmr_cancel(&call->tmr_dtmf); mem_deref(call->sess); mem_deref(call->local_uri); mem_deref(call->local_name); mem_deref(call->peer_uri); mem_deref(call->peer_name); mem_deref(call->audio); #ifdef USE_VIDEO mem_deref(call->video); mem_deref(call->bfcp); #endif mem_deref(call->sdp); mem_deref(call->mnats); mem_deref(call->mencs); mem_deref(call->sub); mem_deref(call->not); mem_deref(call->acc); }
int call_hangup(struct call *call, uint16_t scode, const char *reason) { int err = 0; if (!call) return EINVAL; switch (call->state) { case STATE_INCOMING: if (scode < 400) { scode = 486; reason = "Rejected"; } info("call: rejecting incoming call from %s (%u %s)\n", call->peer_uri, scode, reason); (void)sipsess_reject(call->sess, scode, reason, NULL); break; default: info("call: terminate call '%s' with %s\n", sip_dialog_callid(sipsess_dialog(call->sess)), call->peer_uri); call->sess = mem_deref(call->sess); break; } set_state(call, STATE_TERMINATED); call_stream_stop(call); return err; }
static void menc_error_handler(int err, void *arg) { struct call *call = arg; MAGIC_CHECK(call); warning("call: mediaenc '%s' error: %m\n", call->acc->mencid, err); call_stream_stop(call); call_event_handler(call, CALL_EVENT_CLOSED, "mediaenc failed"); }
static void video_error_handler(int err, const char *str, void *arg) { struct call *call = arg; MAGIC_CHECK(call); warning("call: video device error: %m (%s)\n", err, str); call_stream_stop(call); call_event_handler(call, CALL_EVENT_CLOSED, str); }
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_close_handler(int err, const struct sip_msg *msg, void *arg) { struct call *call = arg; char reason[128] = ""; MAGIC_CHECK(call); if (err) { info("%s: session closed: %m\n", call->peer_uri, err); if (call->not) { (void)call_notify_sipfrag(call, 500, "%m", err); } } else if (msg) { call->scode = msg->scode; (void)re_snprintf(reason, sizeof(reason), "%u %r", msg->scode, &msg->reason); info("%s: session closed: %u %r\n", call->peer_uri, msg->scode, &msg->reason); if (call->not) { (void)call_notify_sipfrag(call, msg->scode, "%r", &msg->reason); } } else { info("%s: session closed\n", call->peer_uri); } call_stream_stop(call); call_event_handler(call, CALL_EVENT_CLOSED, reason); }