subscriber: schedule refresh also when request is in progress

This commit is contained in:
Richard Aas 2011-12-01 09:05:06 +00:00
parent bd45000b46
commit 7d24909807
5 changed files with 32 additions and 20 deletions

View file

@ -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); 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); bool sip_dialog_rseq_valid(struct sip_dialog *dlg, const struct sip_msg *msg);
const char *sip_dialog_callid(const struct sip_dialog *dlg); 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(const struct sip_dialog *dlg, const struct sip_msg *msg);
bool sip_dialog_cmp_half(const struct sip_dialog *dlg, bool sip_dialog_cmp_half(const struct sip_dialog *dlg,
const struct sip_msg *msg); const struct sip_msg *msg);

View file

@ -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) bool sip_dialog_cmp(const struct sip_dialog *dlg, const struct sip_msg *msg)
{ {
if (!dlg || !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)) if (pl_strcmp(msg->req ? &msg->to.tag : &msg->from.tag, dlg->ltag))
return false; return false;
if (dlg->rtag)
return false;
return true; return true;
} }

View file

@ -128,7 +128,9 @@ static void notify_handler(struct sipevent_sock *sock,
switch (ss.state) { switch (ss.state) {
case SIPEVENT_ACTIVE: case SIPEVENT_ACTIVE:
if (sub->req || sub->terminated) sub->subscribed = true;
if (sub->terminated)
break; break;
sipevent_resubscribe(sub, ss.expires * 900); sipevent_resubscribe(sub, ss.expires * 900);

View file

@ -51,4 +51,4 @@ struct sipsub {
}; };
void sipevent_resubscribe(struct sipsub *sub, uint32_t wait); void sipevent_resubscribe(struct sipsub *sub, uint64_t wait);

View file

@ -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<<min(failc, 6)))) * (500 + rand_u16() % 501); return min(1800, (30 * (1<<min(failc, 6)))) * (500 + rand_u16() % 501);
} }
@ -102,6 +102,9 @@ static void tmr_handler(void *arg)
struct sipsub *sub = arg; struct sipsub *sub = arg;
int err; int err;
if (sub->req)
return;
if (!sub->dlg) { if (!sub->dlg) {
err = sip_dialog_alloc(&sub->dlg, sub->uri, sub->uri, 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) if (!wait)
wait = failwait(++sub->failc); 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); 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; const struct sip_hdr *minexp;
struct sipsub *sub = arg; struct sipsub *sub = arg;
uint32_t wait; uint64_t wait;
wait = failwait(sub->failc + 1); 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) { else if (msg->scode < 300) {
if (!sub->subscribed) { if (!sip_dialog_established(sub->dlg)) {
err = sip_dialog_create(sub->dlg, msg); err = sip_dialog_create(sub->dlg, msg);
if (err) { if (err) {
@ -173,22 +176,21 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg)
sub->failc++; sub->failc++;
goto out; goto out;
} }
sub->subscribed = true;
} }
else { else {
(void)sip_dialog_update(sub->dlg, msg); (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->refer = false;
sub->failc = 0; sub->failc = 0;
if (pl_isset(&msg->expires))
wait = pl_u32(&msg->expires);
else
wait = DEFAULT_EXPIRES;
wait *= 900;
} }
else { else {
if (sub->terminated && !sub->subscribed) if (sub->terminated && !sub->subscribed)
@ -248,9 +250,13 @@ static void response_handler(int err, const struct sip_msg *msg, void *arg)
} }
else { else {
if (sub->retry || sub->subscribed) { 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); tmr_start(&sub->tmr, wait, tmr_handler, sub);
} }
else {
tmr_cancel(&sub->tmr);
}
sub->resph(err, msg, sub->arg); sub->resph(err, msg, sub->arg);
} }
} }