int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg, uint16_t scode, const char *reason, struct mbuf *desc, const char *fmt, va_list *ap) { struct sipsess_reply *reply; struct sip_contact contact; int err = ENOMEM; reply = mem_zalloc(sizeof(*reply), destructor); if (!reply) goto out; list_append(&sess->replyl, &reply->le, reply); reply->seq = msg->cseq.num; reply->msg = mem_ref((void *)msg); reply->sess = sess; sip_contact_set(&contact, sess->cuser, &msg->dst, msg->tp); err = sip_treplyf(&sess->st, &reply->mb, sess->sip, msg, true, scode, reason, "%H" "%v" "%s%s%s" "Content-Length: %zu\r\n" "\r\n" "%b", sip_contact_print, &contact, fmt, ap, desc ? "Content-Type: " : "", desc ? sess->ctype : "", desc ? "\r\n" : "", desc ? mbuf_get_left(desc) : (size_t)0, desc ? mbuf_buf(desc) : NULL, desc ? mbuf_get_left(desc) : (size_t)0); if (err) goto out; tmr_start(&reply->tmr, 64 * SIP_T1, tmr_handler, reply); tmr_start(&reply->tmrg, SIP_T1, retransmit_handler, reply); if (!mbuf_get_left(msg->mb) && desc) { reply->awaiting_answer = true; sess->awaiting_answer = true; } out: if (err) { sess->st = mem_deref(sess->st); mem_deref(reply); } return err; }
static int send_handler(enum sip_transp tp, const struct sa *src, const struct sa *dst, struct mbuf *mb, void *arg) { struct sip_contact contact; struct sipsess *sess = arg; (void)dst; sip_contact_set(&contact, sess->cuser, src, tp); return mbuf_printf(mb, "%H", sip_contact_print, &contact); }
int sipnot_reply(struct sipnot *not, const struct sip_msg *msg, uint16_t scode, const char *reason) { struct sip_contact contact; uint32_t expires; expires = (uint32_t)(tmr_get_expire(¬->tmr) / 1000); sip_contact_set(&contact, not->cuser, &msg->dst, msg->tp); return sip_treplyf(NULL, NULL, not->sip, msg, true, scode, reason, "%H" "Expires: %u\r\n" "Content-Length: 0\r\n" "\r\n", sip_contact_print, &contact, expires); }
static void handle_options(struct ua *ua, const struct sip_msg *msg) { struct sip_contact contact; struct call *call = NULL; struct mbuf *desc = NULL; int err; err = ua_call_alloc(&call, ua, VIDMODE_ON, NULL, NULL, NULL); if (err) { (void)sip_treply(NULL, uag.sip, msg, 500, "Call Error"); return; } err = call_sdp_get(call, &desc, true); if (err) goto out; sip_contact_set(&contact, ua_cuser(ua), &msg->dst, msg->tp); err = sip_treplyf(NULL, NULL, uag.sip, msg, true, 200, "OK", "Allow: %s\r\n" "%H" "%H" "Content-Type: application/sdp\r\n" "Content-Length: %zu\r\n" "\r\n" "%b", uag_allowed_methods(), ua_print_supported, ua, sip_contact_print, &contact, mbuf_get_left(desc), mbuf_buf(desc), mbuf_get_left(desc)); if (err) { warning("ua: options: sip_treplyf: %m\n", err); } out: mem_deref(desc); mem_deref(call); }