Exemplo n.º 1
0
static int send_handler(enum sip_transp tp, const struct sa *src,
			const struct sa *dst, struct mbuf *mb, void *arg)
{
	struct sipreg *reg = arg;
	int err;

	(void)dst;

	if (reg->expires > 0) {
		reg->laddr = *src;
		reg->tp = tp;
	}

	err = mbuf_printf(mb, "Contact: <sip:%s@%J%s>;expires=%u%s%s",
			  reg->cuser, &reg->laddr, sip_transp_param(reg->tp),
			  reg->expires,
			  reg->params ? ";" : "",
			  reg->params ? reg->params : "");

	if (reg->regid > 0)
		err |= mbuf_printf(mb, ";reg-id=%d", reg->regid);

	err |= mbuf_printf(mb, "\r\n");

	return err;
}
Exemplo n.º 2
0
static bool contact_handler(const struct sip_hdr *hdr,
			    const struct sip_msg *msg, void *arg)
{
	struct sipreg *reg = arg;
	struct sip_addr c;
	struct pl pval;
	char uri[256];

	if (sip_addr_decode(&c, &hdr->val))
		return false;

	if (re_snprintf(uri, sizeof(uri), "sip:%s@%J%s", reg->cuser,
			&reg->laddr, sip_transp_param(reg->tp)) < 0)
		return false;

	if (pl_strcmp(&c.auri, uri))
		return false;

	if (!sip_param_decode(&c.params, "expires", &pval)) {
	        reg->wait = pl_u32(&pval);
	}
	else if (pl_isset(&msg->expires))
	        reg->wait = pl_u32(&msg->expires);
	else
	        reg->wait = DEFAULT_EXPIRES;

	return true;
}
Exemplo n.º 3
0
/**
 * Send progress response
 *
 * @param sess      SIP Session
 * @param scode     Response status code
 * @param reason    Response reason phrase
 * @param desc      Content description (e.g. SDP)
 * @param fmt       Formatted strings with extra SIP Headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sipsess_progress(struct sipsess *sess, uint16_t scode, const char *reason,
		     struct mbuf *desc, const char *fmt, ...)
{
	va_list ap;
	int err;

	if (!sess || !sess->st || !sess->msg || scode < 101 || scode > 199)
		return EINVAL;

	va_start(ap, fmt);

	err = sip_treplyf(&sess->st, NULL, sess->sip, sess->msg, true,
			  scode, reason,
			  "Contact: <sip:%s@%J%s>\r\n"
			  "%v"
			  "%s%s%s"
			  "Content-Length: %zu\r\n"
			  "\r\n"
			  "%b",
			  sess->cuser, &sess->msg->dst,
			  sip_transp_param(sess->msg->tp),
			  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);

	va_end(ap);

	return err;
}
Exemplo n.º 4
0
/**
 * Accept an incoming SIP Session connection
 *
 * @param sessp     Pointer to allocated SIP Session
 * @param sock      SIP Session socket
 * @param msg       Incoming SIP message
 * @param scode     Response status code
 * @param reason    Response reason phrase
 * @param cuser     Contact username
 * @param ctype     Session content-type
 * @param desc      Content description (e.g. SDP)
 * @param authh     SIP Authentication handler
 * @param aarg      Authentication handler argument
 * @param aref      True to mem_ref() aarg
 * @param offerh    Session offer handler
 * @param answerh   Session answer handler
 * @param estabh    Session established handler
 * @param infoh     Session info handler
 * @param referh    Session refer handler
 * @param closeh    Session close handler
 * @param arg       Handler argument
 * @param fmt       Formatted strings with extra SIP Headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sipsess_accept(struct sipsess **sessp, struct sipsess_sock *sock,
		   const struct sip_msg *msg, uint16_t scode,
		   const char *reason, const char *cuser, const char *ctype,
		   struct mbuf *desc,
		   sip_auth_h *authh, void *aarg, bool aref,
		   sipsess_offer_h *offerh, sipsess_answer_h *answerh,
		   sipsess_estab_h *estabh, sipsess_info_h *infoh,
		   sipsess_refer_h *referh, sipsess_close_h *closeh,
		   void *arg, const char *fmt, ...)
{
	struct sipsess *sess;
	va_list ap;
	int err;

	if (!sessp || !sock || !msg || scode < 101 || scode > 299 ||
	    !cuser || !ctype)
		return EINVAL;

	err = sipsess_alloc(&sess, sock, cuser, ctype, NULL, authh, aarg, aref,
			    offerh, answerh, NULL, estabh, infoh, referh,
			    closeh, arg);
	if (err)
		return err;

	err = sip_dialog_accept(&sess->dlg, msg);
	if (err)
		goto out;

	hash_append(sock->ht_sess,
		    hash_joaat_str(sip_dialog_callid(sess->dlg)),
		    &sess->he, sess);

	sess->msg = mem_ref((void *)msg);

	err = sip_strans_alloc(&sess->st, sess->sip, msg, cancel_handler,
			       sess);
	if (err)
		goto out;

	va_start(ap, fmt);

	if (scode >= 200)
		err = sipsess_reply_2xx(sess, msg, scode, reason, desc,
					fmt, &ap);
	else
		err = sip_treplyf(&sess->st, NULL, sess->sip,
				  msg, true, scode, reason,
				  "Contact: <sip:%s@%J%s>\r\n"
				  "%v"
				  "%s%s%s"
				  "Content-Length: %zu\r\n"
				  "\r\n"
				  "%b",
				  sess->cuser, &msg->dst,
				  sip_transp_param(msg->tp),
				  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);

	va_end(ap);

	if (err)
		goto out;

 out:
	if (err)
		mem_deref(sess);
	else
		*sessp = sess;

	return err;
}