コード例 #1
0
ファイル: accept.c プロジェクト: JackKingChen/unitest
/**
 * 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;
}
コード例 #2
0
ファイル: listen.c プロジェクト: tamy83/baresip-android-mtt
static void bye_handler(struct sipsess_sock *sock, const struct sip_msg *msg)
{
	struct sip *sip = sock->sip;
	struct sipsess *sess;

	sess = sipsess_find(sock, msg);
	if (!sess) {
		(void)sip_reply(sip, msg, 481, "Call Does Not Exist");
		return;
	}

	if (!sip_dialog_rseq_valid(sess->dlg, msg)) {
		(void)sip_reply(sip, msg, 500, "Server Internal Error");
		return;
	}

	(void)sip_treplyf(NULL, NULL, sip, msg, false, 200, "OK",
			  "%s"
			  "Content-Length: 0\r\n"
			  "\r\n",
			  sess->close_hdrs);

	sess->peerterm = true;

	if (sess->terminated)
		return;

	if (sess->st) {
		(void)sip_treply(&sess->st, sess->sip, sess->msg,
				 487, "Request Terminated");
	}

	sipsess_terminate(sess, ECONNRESET, NULL);
}
コード例 #3
0
ファイル: ua.c プロジェクト: pasichnichenko/baresip
/* Handle incoming calls */
static void sipsess_conn_handler(const struct sip_msg *msg, void *arg)
{
	const struct sip_hdr *hdr;
	struct ua *ua;
	struct call *call = NULL;
	char to_uri[256];
	int err;

	(void)arg;

	ua = uag_find(&msg->uri.user);
	if (!ua) {
		warning("ua: %r: UA not found: %r\n",
			&msg->from.auri, &msg->uri.user);
		(void)sip_treply(NULL, uag_sip(), msg, 404, "Not Found");
		return;
	}

	/* handle multiple calls */
	if (list_count(&ua->calls) + 1 > MAX_CALLS) {
		info("ua: rejected call from %r (maximum %d calls)\n",
		     &msg->from.auri, MAX_CALLS);
		(void)sip_treply(NULL, uag.sip, msg, 486, "Busy Here");
		return;
	}

	/* Handle Require: header, check for any required extensions */
	hdr = sip_msg_hdr_apply(msg, true, SIP_HDR_REQUIRE,
				require_handler, ua);
	if (hdr) {
		info("ua: call from %r rejected with 420"
			     " -- option-tag '%r' not supported\n",
			     &msg->from.auri, &hdr->val);

		(void)sip_treplyf(NULL, NULL, uag.sip, msg, false,
				  420, "Bad Extension",
				  "Unsupported: %r\r\n"
				  "Content-Length: 0\r\n\r\n",
				  &hdr->val);
		return;
	}

	(void)pl_strcpy(&msg->to.auri, to_uri, sizeof(to_uri));

	err = ua_call_alloc(&call, ua, VIDMODE_ON, msg, NULL, to_uri);
	if (err) {
		warning("ua: call_alloc: %m\n", err);
		goto error;
	}

	err = call_accept(call, uag.sock, msg);
	if (err)
		goto error;

	return;

 error:
	mem_deref(call);
	(void)sip_treply(NULL, uag.sip, msg, 500, "Call Error");
}
コード例 #4
0
ファイル: subscriber.c プロジェクト: mralexgray/baresip
static void notify_handler(struct sip *sip, const struct sip_msg *msg,
			   void *arg)
{
	enum presence_status status = PRESENCE_CLOSED;
	struct presence *pres = arg;
	const struct sip_hdr *hdr;
	struct pl pl;

	pres->failc = 0;

	hdr = sip_msg_hdr(msg, SIP_HDR_CONTENT_TYPE);
	if (!hdr || 0 != pl_strcasecmp(&hdr->val, "application/pidf+xml")) {

		if (hdr)
			(void)re_printf("presence: unsupported"
					" content-type: '%r'\n",
					&hdr->val);

		sip_treplyf(NULL, NULL, sip, msg, false,
			    415, "Unsupported Media Type",
			    "Accept: application/pidf+xml\r\n"
			    "Content-Length: 0\r\n"
			    "\r\n");
		return;
	}

	if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb),
		      "<status>[^<]*<basic>[^<]*</basic>[^<]*</status>",
		      NULL, &pl, NULL)) {

		if (!pl_strcasecmp(&pl, "open"))
			status = PRESENCE_OPEN;
	}

	if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb),
		      "<rpid:away/>")) {

		status = PRESENCE_CLOSED;
	}
	else if (!re_regex((const char *)mbuf_buf(msg->mb),
			   mbuf_get_left(msg->mb),
			   "<rpid:busy/>")) {

		status = PRESENCE_BUSY;
	}
	else if (!re_regex((const char *)mbuf_buf(msg->mb),
			   mbuf_get_left(msg->mb),
			   "<rpid:on-the-phone/>")) {

		status = PRESENCE_BUSY;
	}

	(void)sip_treply(NULL, sip, msg, 200, "OK");

	contact_set_presence(pres->contact, status);
}
コード例 #5
0
ファイル: reply.c プロジェクト: Issic47/libre
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;
}
コード例 #6
0
ファイル: listen.c プロジェクト: lmangani/libre
static void reinvite_handler(struct sipsess_sock *sock,
			     const struct sip_msg *msg)
{
	struct sip *sip = sock->sip;
	struct sipsess *sess;
	struct mbuf *desc;
	char m[256];
	int err;

	sess = sipsess_find(sock, msg);
	if (!sess || sess->terminated) {
		(void)sip_treply(NULL, sip, msg, 481, "Call Does Not Exist");
		return;
	}

	if (!sip_dialog_rseq_valid(sess->dlg, msg)) {
		(void)sip_treply(NULL, sip, msg, 500, "Server Internal Error");
		return;
	}

	if (sess->st || sess->awaiting_answer) {
		(void)sip_treplyf(NULL, NULL, sip, msg, false,
				  500, "Server Internal Error",
				  "Retry-After: 5\r\n"
				  "Content-Length: 0\r\n"
				  "\r\n");
		return;
	}

	if (sess->req) {
		(void)sip_treply(NULL, sip, msg, 491, "Request Pending");
		return;
	}

	err = sess->offerh(&desc, msg, sess->arg);
	if (err) {
		(void)sip_reply(sip, msg, 488, str_error(err, m, sizeof(m)));
		return;
	}

	(void)sip_dialog_update(sess->dlg, msg);
	(void)sipsess_reply_2xx(sess, msg, 200, "OK", desc,
				NULL, NULL);

	/* pending modifications considered outdated;
	   sdp may have changed in above exchange */
	sess->desc = mem_deref(sess->desc);
	sess->modify_pending = false;
	tmr_cancel(&sess->tmr);
	mem_deref(desc);
}
コード例 #7
0
ファイル: accept.c プロジェクト: JackKingChen/unitest
/**
 * Reject an incoming SIP Session connection
 *
 * @param sess      SIP Session
 * @param scode     Response status code
 * @param reason    Response reason phrase
 * @param fmt       Formatted strings with extra SIP Headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sipsess_reject(struct sipsess *sess, uint16_t scode, const char *reason,
		   const char *fmt, ...)
{
	va_list ap;
	int err;

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

	va_start(ap, fmt);
	err = sip_treplyf(&sess->st, NULL, sess->sip, sess->msg, false,
			  scode, reason, fmt ? "%v" : NULL, fmt, &ap);
	va_end(ap);

	return err;
}
コード例 #8
0
ファイル: notify.c プロジェクト: tamy83/baresip-android-mtt
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(&not->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);
}
コード例 #9
0
ファイル: ua.c プロジェクト: pasichnichenko/baresip
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);
}
コード例 #10
0
ファイル: listen.c プロジェクト: lmangani/libre
static void bye_handler(struct sipsess_sock *sock, const struct sip_msg *msg)
{
	struct sip *sip = sock->sip;
	struct sipsess *sess;
	// char tmp[256];

	sess = sipsess_find(sock, msg);
	if (!sess) {
		(void)sip_reply(sip, msg, 481, "Call Does Not Exist");
		return;
	}

	if (!sip_dialog_rseq_valid(sess->dlg, msg)) {
		(void)sip_reply(sip, msg, 500, "Server Internal Error");
		return;
	}

	/* QXIP */
        if (sess->xrtpstats && !sess->xrtpstats[0] == '\0') {
	/* Inject X-RTP-Stat header */
		(void)sip_treplyf(NULL, NULL, sip, msg, false,
                                  200, "OK",
				  "X-RTP-Stat: %s\r\nContent-Length: 0\r\n\r\n", sess->xrtpstats);
        } else {
	/* Vanilla 200 OK */
		(void)sip_treply(NULL, sip, msg, 200, "OK");
	}

	sess->peerterm = true;

	if (sess->terminated)
		return;

	if (sess->st) {
		(void)sip_treply(&sess->st, sess->sip, sess->msg,
				 487, "Request Terminated");
	}

	sipsess_terminate(sess, ECONNRESET, NULL);
}
コード例 #11
0
ファイル: accept.c プロジェクト: JackKingChen/unitest
/**
 * 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;
}
コード例 #12
0
ファイル: subscriber.c プロジェクト: QXIP/baresip
static void notify_handler(struct sip *sip, const struct sip_msg *msg,
			   void *arg)
{
	enum presence_status status = PRESENCE_CLOSED;
	struct presence *pres = arg;
	const struct sip_hdr *type_hdr, *length_hdr;
	struct pl pl;

	pres->failc = 0;

	type_hdr = sip_msg_hdr(msg, SIP_HDR_CONTENT_TYPE);

	if (!type_hdr) {

		length_hdr = sip_msg_hdr(msg, SIP_HDR_CONTENT_LENGTH);
		if (0 == pl_strcmp(&length_hdr->val, "0")) {

			status = PRESENCE_UNKNOWN;
			goto done;
		}
	}

	if (!type_hdr ||
	    0 != pl_strcasecmp(&type_hdr->val, "application/pidf+xml")) {

		if (type_hdr)
			warning("presence: unsupported content-type: '%r'\n",
				&type_hdr->val);

		sip_treplyf(NULL, NULL, sip, msg, false,
			    415, "Unsupported Media Type",
			    "Accept: application/pidf+xml\r\n"
			    "Content-Length: 0\r\n"
			    "\r\n");
		return;
	}

	if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb),
		      "<basic>[^<]+</basic>", &pl)) {
		if (!pl_strcasecmp(&pl, "open"))
			status = PRESENCE_OPEN;
	}

	if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb),
		      "<rpid:away/>")) {

		status = PRESENCE_CLOSED;
	}
	else if (!re_regex((const char *)mbuf_buf(msg->mb),
			   mbuf_get_left(msg->mb),
			   "<rpid:busy/>")) {

		status = PRESENCE_BUSY;
	}
	else if (!re_regex((const char *)mbuf_buf(msg->mb),
			   mbuf_get_left(msg->mb),
			   "<rpid:on-the-phone/>")) {

		status = PRESENCE_BUSY;
	}

done:
	(void)sip_treply(NULL, sip, msg, 200, "OK");

	contact_set_presence(pres->contact, status);
}