Пример #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);
	}
}
Пример #2
0
static void info_resp_handler(int err, const struct sip_msg *msg, void *arg, void *user_data)
{
	struct sipsess_request *req = arg;

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

	if (msg->scode < 200) {
		return;
	}
	else if (msg->scode < 300) {
		;
	}
	else {
		if (req->sess->terminated)
			goto out;

		switch (msg->scode) {

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

			err = info_request(req);
			if (err)
				break;

			return;

		case 408:
		case 481:
			sipsess_terminate(req->sess, 0, msg);
			break;
		}
	}

 out:
	if (!req->sess->terminated) {
		if (err == ETIMEDOUT)
			sipsess_terminate(req->sess, err, NULL);
		else
			req->resph(err, msg, req->arg, NULL);
	}

	mem_deref(req);
}
Пример #3
0
static void resp_handler(int err, const struct sip_msg *msg, void *arg)
{
    struct sip_req *sr = arg;

    info("baresip.sipreq.resp_handler()\n");

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

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

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

            err = request(sr);
            if (err)
                break;

            return;

        case 403:
            sip_auth_reset(sr->auth);
            break;
        }
    }

out:
    if (sr->resph)
        sr->resph(err, msg, sr->arg);

    /* destroy now */
    mem_deref(sr);
}
Пример #4
0
static void bye_resp_handler(int err, const struct sip_msg *msg, void *arg)
{
    struct sipsess *sess = arg;

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

    if (msg->scode < 200) {
        return;
    }
    else if (msg->scode < 300) {
        ;
    }
    else {
        if (sess->peerterm)
            goto out;

        switch (msg->scode) {

        case 401:
        case 407:
            err = sip_auth_authenticate(sess->auth, msg);
            if (err)
                break;

            err = sipsess_bye(sess, false);
            if (err)
                break;

            return;
        }
    }

out:
    mem_deref(sess);
}
Пример #5
0
static void response_handler(int err, const struct sip_msg *msg, void *arg)
{
	const struct sip_hdr *minexp;
	struct sipreg *reg = arg;

	reg->wait = failwait(reg->failc + 1);

	if (err || sip_request_loops(&reg->ls, msg->scode)) {
		reg->failc++;
		goto out;
	}

	if (msg->scode < 200) {
		return;
	}
	else if (msg->scode < 300) {
		reg->registered = true;
		reg->wait = reg->expires;
		sip_msg_hdr_apply(msg, true, SIP_HDR_CONTACT, contact_handler,
				  reg);
		reg->wait *= 900;
		reg->failc = 0;

		if (reg->regid > 0 && !reg->terminated && !reg->ka)
			start_outbound(reg, msg);
	}
	else {
		if (reg->terminated && !reg->registered)
			goto out;

		switch (msg->scode) {

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

			err = request(reg, false);
			if (err)
				break;

			return;

		case 403:
			sip_auth_reset(reg->auth);
			break;

		case 423:
			minexp = sip_msg_hdr(msg, SIP_HDR_MIN_EXPIRES);
			if (!minexp || !pl_u32(&minexp->val) || !reg->expires)
				break;

			reg->expires = pl_u32(&minexp->val);

			err = request(reg, false);
			if (err)
				break;

			return;
		}

		++reg->failc;
	}

 out:
	if (!reg->expires) {
		mem_deref(reg);
	}
	else if (reg->terminated) {
		if (!reg->registered || request(reg, true))
			mem_deref(reg);
	}
	else {
		tmr_start(&reg->tmr, reg->wait, tmr_handler, reg);
		reg->resph(err, msg, reg->arg);
	}
}
Пример #6
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);
}