diff options
author | Benny Prijono <bennylp@teluu.com> | 2007-11-04 02:05:13 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2007-11-04 02:05:13 +0000 |
commit | 413b4eb2b41e35be24ac9e87fb84885dd72b819a (patch) | |
tree | 52094a7a06ed3347c65838a343c2e5a29625b8eb /pjsip/src/pjsip-ua/sip_reg.c | |
parent | 1d54f22517d1c5c3a958dea0bb46734d8dc27513 (diff) |
Fixed bug with detecting successful unregistration request. Previously, successful unregistration was mistakenly treated as successful registration when it contains no Contact header and has positive Expires header value
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1547 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/pjsip-ua/sip_reg.c')
-rw-r--r-- | pjsip/src/pjsip-ua/sip_reg.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/pjsip/src/pjsip-ua/sip_reg.c b/pjsip/src/pjsip-ua/sip_reg.c index a1edc9b1..3a257473 100644 --- a/pjsip/src/pjsip-ua/sip_reg.c +++ b/pjsip/src/pjsip-ua/sip_reg.c @@ -682,16 +682,20 @@ static void tsx_callback(void *token, pjsip_event *event) int contact_cnt = 0; pjsip_contact_hdr *contact[PJSIP_REGC_MAX_CONTACT]; pjsip_rx_data *rdata; - pj_int32_t expiration = 0xFFFF; + enum { NOEXP = 0x1FFFFFFF }; + pj_int32_t expiration = NOEXP; if (tsx->status_code/100 == 2) { int i; pjsip_contact_hdr *hdr; pjsip_msg *msg; + pj_bool_t has_our_contact = PJ_FALSE; pjsip_expires_hdr *expires; rdata = event->body.tsx_state.src.rdata; msg = rdata->msg_info.msg; + + /* Record all Contact headers in the response */ hdr = (pjsip_contact_hdr*) pjsip_msg_find_hdr( msg, PJSIP_H_CONTACT, NULL); while (hdr) { @@ -703,42 +707,57 @@ static void tsx_callback(void *token, pjsip_event *event) pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, hdr); } + /* Set default expiration value to the value of Expires hdr */ expires = (pjsip_expires_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL); if (expires) expiration = expires->ivalue; + /* Enumerate all Contact headers found in the response and + * find the Contact(s) that we register. + */ for (i=0; i<contact_cnt; ++i) { - hdr = contact[i]; - if (hdr->expires >= 0 && hdr->expires < expiration) { - pjsip_contact_hdr *our_contact; - const pjsip_uri *uri1, *uri2; + pjsip_contact_hdr *our_contact; - our_contact = (pjsip_contact_hdr*) - regc->contact_hdr_list.next; - if ((void*)our_contact==(void*)®c->contact_hdr_list.next) - continue; + our_contact = (pjsip_contact_hdr*) + regc->contact_hdr_list.next; - /* Only set expiration time if this is the same Contact - * that we register. - */ + while ((void*)our_contact != (void*)®c->contact_hdr_list) { + + const pjsip_uri *uri1, *uri2; - /* Exclude the display name when comparing the URI. - * This is because a well known open source proxy server - * doesn't return the display name in the Contact header - * of the REGISTER response. + /* Compare URIs. + * Exclude the display name when comparing the URI since + * server may not return it. */ - uri1 = pjsip_uri_get_uri(hdr->uri); + + uri1 = pjsip_uri_get_uri(contact[i]->uri); uri2 = pjsip_uri_get_uri(our_contact->uri); if (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, uri1, uri2)==0) { - expiration = contact[i]->expires; + has_our_contact = PJ_TRUE; + + if (contact[i]->expires >= 0 && + contact[i]->expires < expiration) + { + /* Get the lowest expiration time. */ + expiration = contact[i]->expires; + } } + + our_contact = our_contact->next; } } - if (regc->auto_reg && expiration != 0 && expiration != 0xFFFF) { + /* When the response doesn't contain our Contact header, that + * means we have been unregistered. + */ + if (!has_our_contact) + expiration = 0; + + /* Schedule next registration */ + if (regc->auto_reg && expiration != 0 && expiration != NOEXP) { pj_time_val delay = { 0, 0}; delay.sec = expiration - DELAY_BEFORE_REFRESH; @@ -769,7 +788,7 @@ static void tsx_callback(void *token, pjsip_event *event) ++regc->busy; /* Call callback. */ - if (expiration == 0xFFFF) expiration = -1; + if (expiration == NOEXP) expiration = -1; call_callback(regc, PJ_SUCCESS, tsx->status_code, (rdata ? &rdata->msg_info.msg->line.status.reason : pjsip_get_status_text(tsx->status_code)), |