summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-11-04 02:05:13 +0000
committerBenny Prijono <bennylp@teluu.com>2007-11-04 02:05:13 +0000
commit413b4eb2b41e35be24ac9e87fb84885dd72b819a (patch)
tree52094a7a06ed3347c65838a343c2e5a29625b8eb /pjsip
parent1d54f22517d1c5c3a958dea0bb46734d8dc27513 (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')
-rw-r--r--pjsip/src/pjsip-ua/sip_reg.c59
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*)&regc->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*)&regc->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)),