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(¬->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); } }
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); }
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); }