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: https://svn.pjsip.org/repos/pjproject/trunk@1547 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/src/pjsip-ua/sip_reg.c b/pjsip/src/pjsip-ua/sip_reg.c
index a1edc9b..3a25747 100644
--- a/pjsip/src/pjsip-ua/sip_reg.c
+++ b/pjsip/src/pjsip-ua/sip_reg.c
@@ -682,16 +682,20 @@
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 @@
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;
+ pjsip_contact_hdr *our_contact;
+
+ our_contact = (pjsip_contact_hdr*)
+ regc->contact_hdr_list.next;
+
+ while ((void*)our_contact != (void*)®c->contact_hdr_list) {
+
const pjsip_uri *uri1, *uri2;
- our_contact = (pjsip_contact_hdr*)
- regc->contact_hdr_list.next;
- if ((void*)our_contact==(void*)®c->contact_hdr_list.next)
- continue;
-
- /* Only set expiration time if this is the same Contact
- * that we register.
+ /* Compare URIs.
+ * Exclude the display name when comparing the URI since
+ * server may not return it.
*/
- /* 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.
- */
- 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 @@
++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)),