Example #1
0
static void response_handler(int err, const struct sip_msg *msg, void *arg)
{
	struct sipnot *not = arg;

	DEBUG_WARNING("re.sipevent.notify.response_handler()\n");

	if (err) {
		if (err == ETIMEDOUT)
			not->subscribed = false;
		goto out;
	}

	if (sip_request_loops(&not->ls, msg->scode)) {
		not->subscribed = false;
		goto out;
	}

	if (msg->scode < 200) {
		return;
	}
	else if (msg->scode < 300) {

		(void)sip_dialog_update(not->dlg, msg);
	}
	else {
		switch (msg->scode) {

		case 401:
		case 407:
			err = sip_auth_authenticate(not->auth, msg);
			if (err) {
				err = (err == EAUTH) ? 0 : err;
				break;
			}

			err = notify_request(not, false);
			if (err)
				break;

			return;
		}

		not->subscribed = false;
	}

 out:
	if (not->termsent) {
		mem_deref(not);
	}
	else if (not->terminated) {
		if (!not->subscribed || notify_request(not, true))
			mem_deref(not);
	}
	else if (!not->subscribed) {
		sipnot_terminate(not, err, msg, -1);
	}
	else if (not->notify_pending) {
		(void)notify_request(not, true);
	}
}
Example #2
0
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);
}
Example #3
0
static void invite_resp_handler(int err, const struct sip_msg *msg, void *arg)
{
	struct sipsess *sess = arg;
	struct mbuf *desc = NULL;

	if (err || sip_request_loops(&sess->ls, msg->scode))
		goto out;

	if (msg->scode < 200) {
		sess->progrh(msg, sess->arg);
		return;
	}
	else if (msg->scode < 300) {

		sess->hdrs = mem_deref(sess->hdrs);

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

		if (sess->sent_offer)
			err = sess->answerh(msg, sess->arg);
		else {
			sess->modify_pending = false;
			err = sess->offerh(&desc, msg, sess->arg);
		}

	int err2 = sipsess_ack(sess->sock, sess->dlg, msg->cseq.num,
				   sess->auth, sess->ctype, desc);
    if (err2)
        printf("sipsess - sent first ACK for call %.*s, got err %d (%s)\n", msg->callid.l, msg->callid.p, err2, strerror(err2));
    err |= err2;

		sess->established = true;
		mem_deref(desc);

		if (err || sess->terminated)
			goto out;

		if (sess->modify_pending)
			(void)sipsess_reinvite(sess, true);
		else
			sess->desc = mem_deref(sess->desc);

		sess->estabh(msg, sess->arg);
		return;
	}
	else if (msg->scode < 400) {

		/* Redirect to first Contact */

		if (sess->terminated)
			goto out;

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

		err = invite(sess);
		if (err)
			goto out;

		return;
	}
	else {
		if (sess->terminated)
			goto out;

		switch (msg->scode) {

		case 401:
		case 407:
			err = sip_auth_authenticate(sess->auth, msg);
			if (err) {
				err = (err == EAUTH) ? 0 : err;
				break;
			}

			err = invite(sess);
			if (err)
				break;

			return;
		}
	}

 out:
	if (!sess->terminated)
		sipsess_terminate(sess, err, msg);
	else
		mem_deref(sess);
}