Пример #1
0
int timer_pdomain(pdomain_t* _d)
{
	struct presentity* presentity, *t;

	lock_pdomain(_d);

	presentity = _d->first;

	if (0) LOG(L_ERR, "timer_pdomain: _d=%s d->first=%p\n", _d->name->s, presentity);
	while(presentity) {
		if (timer_presentity(presentity) < 0) {
			LOG(L_ERR, "timer_pdomain(): Error in timer_pdomain\n");
			unlock_pdomain(_d);
			return -1;
		}
		
		     /* Remove the entire record
		      * if it is empty
		      */
		if (presentity->watchers == 0 && presentity->winfo_watchers==0) {
			t = presentity;
			presentity = presentity->next;
			remove_presentity(_d, t);
			free_presentity(t);
		} else {
			presentity = presentity->next;
		}
	}
	
	unlock_pdomain(_d);
	return 0;
}
Пример #2
0
/*
 * Handle a publish Request
 */
int handle_publish(struct sip_msg* _m, char* _domain, char* _s2)
{
	struct pdomain* d;
	struct presentity *p;
	str p_uri = { NULL, 0 };
	int changed;

	get_act_time();
	paerrno = PA_OK;

	if (parse_hfs(_m) < 0) {
		LOG(L_ERR, "handle_publish(): Error while parsing message header\n");
		goto error;
	}

	if (check_message(_m) < 0) {
		LOG(L_ERR, "handle_publish(): Error while checking message\n");
		goto error;
	}

	d = (struct pdomain*)_domain;

	if (get_pres_uri(_m, &p_uri) < 0 || p_uri.s == NULL || p_uri.len == 0) {
		LOG(L_ERR, "handle_publish(): Error while extracting presentity URI\n");
		goto error;
	}

	lock_pdomain(d);
	
	LOG(L_ERR, "handle_publish -4- p_uri=%*.s p_uri.len=%d\n", p_uri.len, p_uri.s, p_uri.len);
	if (find_presentity(d, &p_uri, &p) > 0) {
		changed = 1;
		if (create_presentity_only(_m, d, &p_uri, &p) < 0) {
			goto error2;
		}
	}

	/* update presentity event state */
	LOG(L_ERR, "handle_publish -5- presentity=%p\n", p);
	if (p)
		publish_presentity(_m, d, p, &changed);

	unlock_pdomain(d);

	if (send_reply(_m) < 0) return -1;

	LOG(L_ERR, "handle_publish -8- paerrno=%d\n", paerrno);
	return 1;
	
 error2:
	unlock_pdomain(d);
 error:
	send_reply(_m);
	return 0;
}
Пример #3
0
int handle_publish(struct sip_msg* _m, char* _domain, char* _s2)
{
	struct pdomain* d;
	struct presentity *p;
	str p_uri = STR_NULL;
	str uid = STR_NULL;
	xcap_query_params_t xcap_params;

	get_act_time();
	paerrno = PA_OK;

	if (parse_publish_hfs(_m) < 0) {
		LOG(L_ERR, "handle_publish(): Error while parsing message header\n");
		goto error;
	}

	d = (struct pdomain*)_domain;

	if (get_pres_uri(_m, &p_uri) < 0 || p_uri.s == NULL || p_uri.len == 0) {
		LOG(L_ERR, "handle_publish(): Error while extracting presentity URI\n");
		goto error;
	}

	if (get_presentity_uid(&uid, _m) < 0) {
		ERR("Error while extracting presentity UID\n");
		goto error;
	}

	lock_pdomain(d);

	if (find_presentity_uid(d, &uid, &p) > 0) {
		memset(&xcap_params, 0, sizeof(xcap_params));
		if (fill_xcap_params) fill_xcap_params(_m, &xcap_params);
		if (new_presentity(d, &p_uri, &uid, &xcap_params, &p) < 0) {
			LOG(L_ERR, "handle_publish can't create presentity\n");
			goto error2;
		}
	}

	/* update presentity event state */
	if (p) publish_presentity(_m, d, p);

	unlock_pdomain(d);

	if (send_reply(_m) < 0) return -1;

	return 1;

error2:
	unlock_pdomain(d);
error:
	send_reply(_m);
	return 0;
}
Пример #4
0
/*
 * Returns 1 if subscription exists and -1 if not
 */
int existing_subscription(struct sip_msg* _m, char* _domain, char* _s2)
{
	struct pdomain* d;
	struct presentity* p;
	struct watcher* w;
	str p_uri, w_uri;
	str w_dn;
	int et = 0;
	if (_m->event) {
		event_t *event = (event_t*)(_m->event->parsed);
		et = event->parsed;
	} else {
		LOG(L_ERR, "existing_subscription defaulting to EVENT_PRESENCE\n");
		et = EVENT_PRESENCE;
	}

	paerrno = PA_OK;

	if (parse_from_header(_m) < 0) {
		paerrno = PA_PARSE_ERR;
		LOG(L_ERR, "existing_subscription(): Error while parsing From header field\n");
		goto error;
	}

	d = (struct pdomain*)_domain;

	if (get_pres_uri(_m, &p_uri) < 0) {
		LOG(L_ERR, "existing_subscription(): Error while extracting presentity URI\n");
		goto error;
	}

	if (get_watch_uri(_m, &w_uri, &w_dn) < 0) {
		LOG(L_ERR, "existing_subscription(): Error while extracting watcher URI\n");
		goto error;
	}

	lock_pdomain(d);
	
	if (find_presentity(d, &p_uri, &p) == 0) {
		if (find_watcher(p, &w_uri, et, &w) == 0) {
			LOG(L_ERR, "existing_subscription() found watcher\n");
			unlock_pdomain(d);
			return 1;
		}
	}

	unlock_pdomain(d);
	return -1;

 error:
	send_reply(_m);       
	return 0;
}
Пример #5
0
/*
 * Function registers a new domain with presence agent
 * if the domain exists, pointer to existing structure
 * will be returned, otherwise a new domain will be
 * created
 */
int register_pdomain(const char* _n, pdomain_t** _d)
{
    pdomain_t *pdomain;
    dlist_t* d;
    str s;

    s.s = (char*)_n;
    s.len = strlen(_n);

    if (find_dlist(&s, &d) == 0) {
        *_d = d->d;
        return 0;
    }

    if (new_dlist(&s, &d) < 0) {
        LOG(L_ERR, "register_pdomain(): Error while creating new domain\n");
        return -1;
    }

    pdomain = d->d;
    lock_pdomain(pdomain);	/* do not enable timer to delete presentities in it */
    d->next = root;
    root = d;

    *_d = pdomain;

    /* Preload domain with data from database if we are gonna
     * to use database
     */
    pdomain_load_presentities(pdomain);
    unlock_pdomain(pdomain);

    return 0;
}
Пример #6
0
static void refresh_dialog(pa_notify_cb_param_t *cbd, struct sip_msg *m)
{
    watcher_t *w;
    presentity_t *p;

    lock_pdomain(cbd->domain);
    if (get_watcher(cbd, &w, &p) >= 0)
        tmb.dlg_response_uac(w->dialog, m, notify_is_refresh != 0 ? IS_TARGET_REFRESH : IS_NOT_TARGET_REFRESH);
    unlock_pdomain(cbd->domain);
}
Пример #7
0
static void destroy_subscription(pa_notify_cb_param_t *cbd)
{
    presentity_t *p = NULL;
    watcher_t *w = NULL;

    /*	if (find_pdomain(cbd->domain, &domain) != 0) {
    		ERR("can't find PA domain\n");
    		return;
    	} */
    lock_pdomain(cbd->domain);

    if (get_watcher(cbd, &w, &p) != 0) {
        unlock_pdomain(cbd->domain);
        return;
    }

    remove_watcher(p, w);
    free_watcher(w);

    unlock_pdomain(cbd->domain);

}
Пример #8
0
/*
 * Free all memory allocated for
 * the domain
 */
void free_pdomain(pdomain_t* _d)
{
	int i;
	
	lock_pdomain(_d);
	if (_d->table) {
		for(i = 0; i < _d->size; i++) {
			deinit_slot(_d->table + i);
		}
		mem_free(_d->table);
	}
	unlock_pdomain(_d);

        mem_free(_d);
}
Пример #9
0
int fifo_pa_watcherinfo(FILE *fifo, char *response_file)
{
     char pdomain_s[MAX_P_URI];
     char p_uri_s[MAX_P_URI];
     pdomain_t *pdomain = NULL;
     presentity_t *presentity = NULL;
     str pdomain_name, p_uri;

     if (!read_line(pdomain_s, MAX_PDOMAIN, fifo, &pdomain_name.len) || pdomain_name.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_watcherinfo: pdomain expected\n");
	  LOG(L_ERR, "ERROR: pa_watcherinfo: pdomain expected\n");
	  return 1;
     }
     pdomain_name.s = pdomain_s;

     if (!read_line(p_uri_s, MAX_P_URI, fifo, &p_uri.len) || p_uri.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_watcherinfo: p_uri expected\n");
	  LOG(L_ERR, "ERROR: pa_watcherinfo: p_uri expected\n");
	  return 1;
     }
     p_uri.s = p_uri_s;

     register_pdomain(pdomain_s, &pdomain);
     if (!pdomain) {
	  fifo_reply(response_file, "400 could not register pdomain\n");
	  LOG(L_ERR, "ERROR: pa_watcherinfo: could not register pdomain %.*s\n",
	      pdomain_name.len, pdomain_name.s);
	  return 1;
     }

     lock_pdomain(pdomain);

     find_presentity(pdomain, &p_uri, &presentity);
     if (presentity) {
       db_read_watcherinfo(presentity);
     }

     unlock_pdomain(pdomain);

     fifo_reply(response_file, "200 watcherinfo updated\n",
		"(%.*s)\n",
		p_uri.len, ZSW(p_uri.s));
     return 1;
}
Пример #10
0
/*
 * contact will be NULL if user is offline
 * fixme:locking
 */
void callback(str* _user, str *_contact, int state, void* data)
{
     presentity_t *presentity;

     get_act_time();

     presentity = (struct presentity*)data;

     if (presentity && callback_update_db) {
	  presence_tuple_t *tuple = NULL;
	  int orig;
	  LOG(L_ERR, "callback: uri=%.*s contact=%.*s state=%d\n",
	      presentity->uri.len, presentity->uri.s, (_contact ? _contact->len : 0), (_contact ? _contact->s : ""), state);
	  if (_contact) {
	       if (callback_lock_pdomain)
		    lock_pdomain(presentity->pdomain);

	       find_presence_tuple(_contact, presentity, &tuple);
	       if (!tuple) {
		    new_presence_tuple(_contact, act_time + default_expires, presentity, &tuple);
		    add_presence_tuple(presentity, tuple);
	       };

	       orig = tuple->state;

	       if (state == 0) {
		    tuple->state = PS_OFFLINE;
	       } else {
		    tuple->state = PS_ONLINE;
	       }

	       tuple->expires = act_time + default_expires;

	       db_update_presentity(presentity);

	       if (orig != state) {
		    presentity->flags |= PFLAG_PRESENCE_CHANGED;
	       }

	       if (callback_lock_pdomain)
		    unlock_pdomain(presentity->pdomain);
	  }
     }
}
Пример #11
0
int timer_pdomain(pdomain_t* _d)
{
	struct presentity* presentity, *t;
	time_t start, stop;

	PROF_START(pa_timer_pdomain)
	lock_pdomain(_d);
	start = time(NULL);

	presentity = _d->first;

	while(presentity) {
		if (timer_presentity(presentity) < 0) {
			LOG(L_ERR, "timer_pdomain(): Error in timer_pdomain\n");
			unlock_pdomain(_d);
			PROF_STOP(pa_timer_pdomain)
			return -1;
		}
		
		/* Remove the entire record
		 * if it is empty
		 */
		if ( (!presentity->first_watcher) && 
				(!presentity->first_winfo_watcher) && 
				(!presentity->data.first_tuple) &&
				(!presentity->data.first_note) &&
				(!presentity->data.first_unknown_element) &&
				(!presentity->first_qsa_subscription) &&
				(presentity->ref_cnt == 0)) {
			LOG(L_DBG, "timer_pdomain(): removing empty presentity\n");
			t = presentity;
			presentity = presentity->next;
			release_presentity(t);
		} else {
			presentity = presentity->next;
		}
	}
Пример #12
0
int fifo_pa_location_contact(FILE *fifo, char *response_file)
{
     char pdomain_s[MAX_P_URI];
     char p_uri_s[MAX_P_URI];
     char p_contact_s[MAX_P_URI];
     char location_s[MAX_LOCATION];
     char priority_s[MAX_LOCATION];
     char expires_s[MAX_LOCATION];
     pdomain_t *pdomain = NULL;
     presentity_t *presentity = NULL;
     presence_tuple_t *tuple = NULL;
     str pdomain_name, p_uri, p_contact, location, priority_str, expires_str;
     time_t expires;
     double priority;
     int changed = 0;
     char *msg = "no error";

     if (!read_line(pdomain_s, MAX_PDOMAIN, fifo, &pdomain_name.len) || pdomain_name.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_location_contact: pdomain expected\n");
	  LOG(L_ERR, "ERROR: pa_location_contact: pdomain expected\n");
	  return 1;
     }
     pdomain_name.s = pdomain_s;

     if (!read_line(p_uri_s, MAX_P_URI, fifo, &p_uri.len) || p_uri.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_location_contact: p_uri expected\n");
	  LOG(L_ERR, "ERROR: pa_location_contact: p_uri expected\n");
	  return 1;
     }
     p_uri.s = p_uri_s;

     if (!read_line(p_contact_s, MAX_P_URI, fifo, &p_contact.len) || p_contact.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_location_contact: p_contact expected\n");
	  LOG(L_ERR, "ERROR: pa_location_contact: p_contact expected\n");
	  return 1;
     }
     p_contact.s = p_contact_s;

     if (!read_line(location_s, MAX_LOCATION, fifo, &location.len) || location.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_location_contact: location expected\n");
	  LOG(L_ERR, "ERROR: pa_location_contact: location expected\n");
	  return 1;
     }
     location.s = location_s;

     if (!read_line(priority_s, MAX_LOCATION, fifo, &priority_str.len) || priority_str.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_location_contact: priority expected\n");
	  LOG(L_ERR, "ERROR: pa_location_contact: priority expected\n");
	  return 1;
     }
     priority = strtod(priority_s, NULL);

     if (!read_line(expires_s, MAX_LOCATION, fifo, &expires_str.len) || expires_str.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_location_contact: expires expected\n");
	  LOG(L_ERR, "ERROR: pa_location_contact: expires expected\n");
	  return 1;
     }
     expires = strtoul(expires_s, NULL, 0);

     register_pdomain(pdomain_s, &pdomain);
     if (!pdomain) {
	  fifo_reply(response_file, "400 could not register pdomain\n");
	  LOG(L_ERR, "ERROR: pa_location_contact: could not register pdomain %.*s\n",
	      pdomain_name.len, pdomain_name.s);
	  return 1;
     }

     lock_pdomain(pdomain);

     find_presentity(pdomain, &p_uri, &presentity);
     if (!presentity) {
	  new_presentity(pdomain, &p_uri, &presentity);
	  add_presentity(pdomain, presentity);
	  changed = 1;
     }
     if (!presentity) {
	  msg = "400 could not find presentity\n";
	  LOG(L_ERR, "ERROR: pa_location_contact: could not find presentity %.*s\n",
	      p_uri.len, p_uri.s);
	  return 1;
     }

     find_presence_tuple(&p_contact, presentity, &tuple);
     if (!tuple && new_tuple_on_publish) {
       new_presence_tuple(&p_contact, expires, presentity, &tuple);
       add_presence_tuple(presentity, tuple);
       tuple->state = PS_ONLINE;
       changed = 1;
     }
     if (!tuple) {
	  LOG(L_ERR, "publish_presentity: no tuple for %.*s\n", 
	      presentity->uri.len, presentity->uri.s);
	  msg = "400 could not find presence tuple\n";
	  goto error;
     }
     changed = 1;

     if (1 || (tuple->location.loc.len && str_strcasecmp(&tuple->location.room, &location) != 0)) {
       changed = 1;
       LOG(L_ERR, "Setting room of contact=%.*s to %.*s\n",
	   tuple->contact.len, tuple->contact.s,
	   tuple->location.room.len, tuple->location.room.s);
       strncpy(tuple->location.room.s, location.s, location.len);
       tuple->location.room.len = location.len;

       strncpy(tuple->location.loc.s, location.s, location.len);
       tuple->location.loc.len = location.len;
     }

     if (tuple->priority != priority) {
       tuple->priority = priority;
       changed = 1;
     }

     if (expires < 7*24*3600) {
       /* must be seconds */
       get_act_time();
       expires = act_time + expires;
     }
     if (tuple->expires != expires) {
       tuple->expires = expires;
       changed = 1;
     }

     if (changed) {
	  presentity->flags |= PFLAG_PRESENCE_CHANGED;
     }

     db_update_presentity(presentity);

     unlock_pdomain(pdomain);

     fifo_reply(response_file, "200 published\n",
		"(%.*s %.*s)\n",
		p_uri.len, ZSW(p_uri.s),
		location.len, ZSW(location.s));
     return 1;

 error:
     unlock_pdomain(pdomain);
     fifo_reply(response_file, msg);
     return 1;
}
Пример #13
0
int fifo_pa_location(FILE *fifo, char *response_file)
{
     char pdomain_s[MAX_P_URI];
     char p_uri_s[MAX_P_URI];
     char location_s[MAX_LOCATION];
     pdomain_t *pdomain = NULL;
     presentity_t *presentity = NULL;
     presence_tuple_t *tuple = NULL;
     str pdomain_name, p_uri, location;
     int changed = 0;

     if (!read_line(pdomain_s, MAX_PDOMAIN, fifo, &pdomain_name.len) || pdomain_name.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_location: pdomain expected\n");
	  LOG(L_ERR, "ERROR: pa_location: pdomain expected\n");
	  return 1;
     }
     pdomain_name.s = pdomain_s;

     if (!read_line(p_uri_s, MAX_P_URI, fifo, &p_uri.len) || p_uri.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_location: p_uri expected\n");
	  LOG(L_ERR, "ERROR: pa_location: p_uri expected\n");
	  return 1;
     }
     p_uri.s = p_uri_s;

     if (!read_line(location_s, MAX_LOCATION, fifo, &location.len) || location.len == 0) {
	  fifo_reply(response_file,
		     "400 pa_location: location expected\n");
	  LOG(L_ERR, "ERROR: pa_location: location expected\n");
	  return 1;
     }
     location.s = location_s;

     register_pdomain(pdomain_s, &pdomain);
     if (!pdomain) {
	  fifo_reply(response_file, "400 could not register pdomain\n");
	  LOG(L_ERR, "ERROR: pa_location: could not register pdomain %.*s\n",
	      pdomain_name.len, pdomain_name.s);
	  return 1;
     }

     lock_pdomain(pdomain);

     find_presentity(pdomain, &p_uri, &presentity);
     if (!presentity) {
	  new_presentity(pdomain, &p_uri, &presentity);
	  add_presentity(pdomain, presentity);
	  changed = 1;
     }
     if (!presentity) {
	  unlock_pdomain(pdomain);
	  fifo_reply(response_file, "400 could not find presentity\n");
	  LOG(L_ERR, "ERROR: pa_location: could not find presentity %.*s\n",
	      p_uri.len, p_uri.s);
	  return 1;
     }

     changed = 1;
     for (tuple = presentity->tuples; tuple; tuple = tuple->next) {
	  if (tuple->location.loc.len && str_strcasecmp(&tuple->location.room, &location) != 0)
	       changed = 1;

	  LOG(L_ERR, "Setting room of contact=%.*s to %.*s\n",
	      tuple->contact.len, tuple->contact.s,
	      tuple->location.room.len, tuple->location.room.s);
	  strncpy(tuple->location.room.s, location.s, location.len);
	  tuple->location.room.len = location.len;

	  strncpy(tuple->location.loc.s, location.s, location.len);
	  tuple->location.loc.len = location.len;
     }

     if (changed) {
	  presentity->flags |= PFLAG_PRESENCE_CHANGED;
     }

     db_update_presentity(presentity);

     unlock_pdomain(pdomain);

     fifo_reply(response_file, "200 published\n",
		"(%.*s %.*s)\n",
		p_uri.len, ZSW(p_uri.s),
		location.len, ZSW(location.s));
     return 1;
}
Пример #14
0
/*
 * Handle a subscribe Request
 */
int handle_subscription(struct sip_msg* _m, char* _domain, char* _s2)
{
	struct pdomain* d;
	struct presentity *p;
	struct watcher* w;
	str p_uri;

	LOG(L_ERR, "handle_subscription() entered\n");
	get_act_time();
	paerrno = PA_OK;

	if (parse_hfs(_m, 1) < 0) {
		LOG(L_ERR, "handle_subscription(): Error while parsing message header\n");
		goto error;
	}

	if (check_message(_m) < 0) {
		LOG(L_ERR, "handle_subscription(): Error while checking message\n");
		goto error;
	}

	d = (struct pdomain*)_domain;

	if (get_pres_uri(_m, &p_uri) < 0) {
		LOG(L_ERR, "handle_subscription(): Error while extracting presentity URI\n");
		goto error;
	}

	lock_pdomain(d);
	
	if (find_presentity(d, &p_uri, &p) > 0) {
		if (create_presentity(_m, d, &p_uri, &p, &w) < 0) {
			LOG(L_ERR, "handle_subscription(): Error while creating new presentity\n");
			goto error2;
		}
	} else {
		if (update_presentity(_m, d, p, &w) < 0) {
			LOG(L_ERR, "handle_subscription(): Error while updating presentity\n");
			goto error2;
		}
	}

	if (send_reply(_m) < 0) {
	  LOG(L_ERR, "handle_subscription(): Error while sending reply\n");
	  goto error2;
	}

	if (p) {
		p->flags |= PFLAG_WATCHERINFO_CHANGED;
	}
	if (w) {
		w->flags |= WFLAG_SUBSCRIPTION_CHANGED;
	}

	LOG(L_ERR, "handle_subscription about to return 1: w->event_package=%d w->accept=%d p->flags=%x w->flags=%x w=%p\n",
	    (w ? w->event_package : -1), (w ? w->accept : -1), (p ? p->flags : -1), (w ? w->flags : -1), w);
	unlock_pdomain(d);
	return 1;
	
 error2:
	LOG(L_ERR, "handle_subscription about to return -1\n");
	unlock_pdomain(d);
	return -1;
 error:
	LOG(L_ERR, "handle_subscription about to send_reply and return -2\n");
	send_reply(_m);
	return -1;
}
Пример #15
0
int pa_handle_registration(struct sip_msg* _m, char* _domain, char* _s2)
{
     struct pdomain* d = (struct pdomain*)_domain;
     struct presentity *presentity;
     str p_uri;
     struct to_body *from = NULL;
     int e = 0;


     // LOG(L_ERR, "pa_handle_registration() entered\n");
     paerrno = PA_OK;

     d = (struct pdomain*)_domain;

     if (parse_hfs(_m, 0) < 0) {
	  paerrno = PA_PARSE_ERR;
	  LOG(L_ERR, "pa_handle_registration(): Error while parsing headers\n");
	  return -1;
     }

     from = get_from(_m);
     if (!from || (pa_extract_aor(&from->uri, &p_uri) < 0)) {
	  LOG(L_ERR, "pa_handle_registration(): Error while extracting Address Of Record\n");
	  goto error;
     }

     if (_m->expires) {
	  e = ((exp_body_t*)_m->expires->parsed)->val;
     }

     if (from)
       LOG(L_ERR, "pa_handle_registration: from=%.*s p_uri=%.*s expires=%d\n", 
	   from->uri.len, from->uri.s, p_uri.len, p_uri.s, e);

     lock_pdomain(d);
	
     if (find_presentity(d, &p_uri, &presentity) > 0) {
	  LOG(L_ERR, "pa_handle_registration: find_presentity did not find presentity\n");
	  if (e > 0) {
	       if (create_presentity_only(_m, d, &p_uri, &presentity) < 0) {
		    LOG(L_ERR, "pa_handle_registration(): Error while creating new presentity\n");
		    goto error2;
	       }
	  } 
#if 0
	  else {
	       presence_tuple_t *tuple = NULL;
	       if (_m->contact) {
		    struct hdr_field* ptr = _m->contact;
		    while (ptr) {
			 if (ptr->type == HDR_CONTACT) {
			      if (!ptr->parsed && (parse_contact(ptr) < 0)) {
				   goto next;
			      }
			 }
			 if (find_presence_tuple(contact, presentity, &tuple) == 0) {
			      tuple->state = PS_OFFLINE;
			 }
		    next:
			 ptr = ptr->next;
		    }
	       }

	       db_update_presentity(presentity);
	  }
#endif
     }

     if (presentity && e > 0) {
	  LOG(L_ERR, "pa_handle_registration about to call d->reg p=%p expires=%d", presentity, e);
	  d->reg(&presentity->uri, &presentity->uri, (void*)callback, presentity);
     }

     LOG(L_ERR, "pa_handle_registration about to return 1");
     unlock_pdomain(d);
     return 1;
	
 error2:
     LOG(L_ERR, "pa_handle_registration about to return -1\n");
     unlock_pdomain(d);
     return -1;
 error:
     LOG(L_ERR, "pa_handle_registration about to return -2\n");
     return -1;
}