diff --git a/include/re_sip.h b/include/re_sip.h index 4a45e1c..70f349b 100644 --- a/include/re_sip.h +++ b/include/re_sip.h @@ -304,6 +304,7 @@ int sip_dialog_create(struct sip_dialog *dlg, const struct sip_msg *msg); int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg); bool sip_dialog_rseq_valid(struct sip_dialog *dlg, const struct sip_msg *msg); const char *sip_dialog_callid(const struct sip_dialog *dlg); +bool sip_dialog_established(const struct sip_dialog *dlg); bool sip_dialog_cmp(const struct sip_dialog *dlg, const struct sip_msg *msg); bool sip_dialog_cmp_half(const struct sip_dialog *dlg, const struct sip_msg *msg); diff --git a/src/sip/dialog.c b/src/sip/dialog.c index a9b11bf..4282aef 100644 --- a/src/sip/dialog.c +++ b/src/sip/dialog.c @@ -412,6 +412,12 @@ const char *sip_dialog_callid(const struct sip_dialog *dlg) } +bool sip_dialog_established(const struct sip_dialog *dlg) +{ + return dlg && dlg->rtag; +} + + bool sip_dialog_cmp(const struct sip_dialog *dlg, const struct sip_msg *msg) { if (!dlg || !msg) @@ -442,8 +448,5 @@ bool sip_dialog_cmp_half(const struct sip_dialog *dlg, if (pl_strcmp(msg->req ? &msg->to.tag : &msg->from.tag, dlg->ltag)) return false; - if (dlg->rtag) - return false; - return true; } diff --git a/src/sipevent/listen.c b/src/sipevent/listen.c index e687e71..90e24e7 100644 --- a/src/sipevent/listen.c +++ b/src/sipevent/listen.c @@ -128,7 +128,9 @@ static void notify_handler(struct sipevent_sock *sock, switch (ss.state) { case SIPEVENT_ACTIVE: - if (sub->req || sub->terminated) + sub->subscribed = true; + + if (sub->terminated) break; sipevent_resubscribe(sub, ss.expires * 900); diff --git a/src/sipevent/sipevent.h b/src/sipevent/sipevent.h index 5117618..f9e3b3b 100644 --- a/src/sipevent/sipevent.h +++ b/src/sipevent/sipevent.h @@ -51,4 +51,4 @@ struct sipsub { }; -void sipevent_resubscribe(struct sipsub *sub, uint32_t wait); +void sipevent_resubscribe(struct sipsub *sub, uint64_t wait); diff --git a/src/sipevent/subscribe.c b/src/sipevent/subscribe.c index cf0dc92..3cd769b 100644 --- a/src/sipevent/subscribe.c +++ b/src/sipevent/subscribe.c @@ -91,7 +91,7 @@ static void destructor(void *arg) } -static uint32_t failwait(uint32_t failc) +static uint64_t failwait(uint32_t failc) { return min(1800, (30 * (1<req) + return; + if (!sub->dlg) { err = sip_dialog_alloc(&sub->dlg, sub->uri, sub->uri, @@ -128,12 +131,12 @@ static void tmr_handler(void *arg) } -void sipevent_resubscribe(struct sipsub *sub, uint32_t wait) +void sipevent_resubscribe(struct sipsub *sub, uint64_t wait) { if (!wait) wait = failwait(++sub->failc); - re_printf("will re-subscribe in %u ms\n", wait); + re_printf("will re-subscribe in %llu ms\n", wait); tmr_start(&sub->tmr, wait, tmr_handler, sub); } @@ -143,7 +146,7 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg) { const struct sip_hdr *minexp; struct sipsub *sub = arg; - uint32_t wait; + uint64_t wait; wait = failwait(sub->failc + 1); @@ -164,7 +167,7 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg) } else if (msg->scode < 300) { - if (!sub->subscribed) { + if (!sip_dialog_established(sub->dlg)) { err = sip_dialog_create(sub->dlg, msg); if (err) { @@ -173,22 +176,21 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg) sub->failc++; goto out; } - - sub->subscribed = true; } else { (void)sip_dialog_update(sub->dlg, msg); } + if (sub->refer && tmr_isrunning(&sub->tmr)) + wait = tmr_get_expire(&sub->tmr); + else if (pl_isset(&msg->expires)) + wait = pl_u32(&msg->expires) * 900; + else + wait = sub->expires * 900; + + sub->subscribed = true; sub->refer = false; sub->failc = 0; - - if (pl_isset(&msg->expires)) - wait = pl_u32(&msg->expires); - else - wait = DEFAULT_EXPIRES; - - wait *= 900; } else { if (sub->terminated && !sub->subscribed) @@ -248,9 +250,13 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg) } else { if (sub->retry || sub->subscribed) { - re_printf("will re-subscribe in %u ms...\n", wait); + re_printf("will re-subscribe in %llu ms...\n", wait); tmr_start(&sub->tmr, wait, tmr_handler, sub); } + else { + tmr_cancel(&sub->tmr); + } + sub->resph(err, msg, sub->arg); } }