obsolete/pa/pres_timer.c
5d58dfb2
 #include "presentity.h"
 #include "pa_mod.h"
 #include "ptime.h"
 #include "notify.h"
 #include "async_auth.h"
 #include "tuple.h"
 #include "pres_notes.h"
018409d0
 #include "extension_elements.h"
5d58dfb2
 
 static void process_watchers(presentity_t* _p, int *changed)
 {
 	watcher_t *next, *w;
 	int presentity_changed;
 	int notify;
 	
 	/* !!! "changed" is not initialized here it is only set if change
 	 * in presentity occurs */
 	
 	presentity_changed = _p->flags & PFLAG_PRESENCE_CHANGED;
 
 	w = _p->first_watcher;
 	while (w) {
 		/* changes status of expired watcher */
 		if (w->expires <= act_time) {
 			LOG(L_DBG, "Expired watcher %.*s\n", w->uri.len, w->uri.s);
 			w->expires = 0;
 			set_watcher_terminated_status(w);
 			_p->flags |= PFLAG_WATCHERINFO_CHANGED;
 			w->flags |= WFLAG_SUBSCRIPTION_CHANGED;
 			if (changed) *changed = 1;
 		}
 
 		/* send NOTIFY if needed */
 		notify = 0;
 		if ((w->flags & WFLAG_SUBSCRIPTION_CHANGED)) {
 			notify = 1;
 			if (changed) *changed = 1; /* ??? */
 		}
 		if (presentity_changed && is_watcher_authorized(w)) notify = 1;
 		if (notify) send_notify(_p, w);
 		w->flags &= ~WFLAG_SUBSCRIPTION_CHANGED;
 		
 		if (is_watcher_terminated(w)) {
 			next = w->next;
 			remove_watcher(_p, w);
 			free_watcher(w);
 			w = next;
 			if (changed) *changed = 1;
 		}
 		else w = w->next;
 	}
 }
 
 static void process_winfo_watchers(presentity_t* _p, int *changed)
 {
 	watcher_t *next, *w;
 	int notify;
 	
 	/* !!! "changed" is not initialized here it is only set if change
 	 * in presentity occurs */
 	
 	w = _p->first_winfo_watcher;
 	while (w) {
 		/* changes status of expired watcher */
 		if (w->expires <= act_time) {
 			LOG(L_DBG, "Expired watcher %.*s\n", w->uri.len, w->uri.s);
 			w->expires = 0;
 			set_watcher_terminated_status(w);
 			w->flags |= WFLAG_SUBSCRIPTION_CHANGED;
 			if (changed) *changed = 1;
 		}
 
 		/* send NOTIFY if needed */
 		notify = 0;
 		if ((w->flags & WFLAG_SUBSCRIPTION_CHANGED)) {
 			notify = 1;
 			if (changed) *changed = 1; /* ??? */
 		}
 		if ((_p->flags & PFLAG_WATCHERINFO_CHANGED) && 
 			is_watcher_authorized(w)) notify = 1;
 		if (notify) send_notify(_p, w);
 		w->flags &= ~WFLAG_SUBSCRIPTION_CHANGED;
 		
 		if (is_watcher_terminated(w)) {
 			next = w->next;
 			remove_watcher(_p, w);
 			free_watcher(w);
 			w = next;
 			if (changed) *changed = 1;
 		}
 		else w = w->next;
 	}
 }
 
 /* static void mark_expired_tuples(presentity_t *_p, int *changed)
 {
 	presence_tuple_t *t;
 
 	t = _p->tuples;
 	while (t) {	
 		if (t->expires < act_time) {
 			t->state = PS_OFFLINE;
 			if (changed) *changed = 1;
 			_p->flags |= PFLAG_PRESENCE_CHANGED;
 		}
 		t = t->next;
 	}
 }*/
 
 static void remove_expired_tuples(presentity_t *_p, int *changed)
 {
 	presence_tuple_t *t, *n;
 
 	t = (presence_tuple_t*)_p->data.first_tuple;
 	while (t) {
 		n = (presence_tuple_t *)t->data.next;
 		if (t->expires < act_time) {
 			DBG("Expiring tuple %.*s\n", t->data.contact.len, t->data.contact.s);
 			remove_presence_tuple(_p, t);
 			free_presence_tuple(t);
 			if (changed) *changed = 1;
 			_p->flags |= PFLAG_PRESENCE_CHANGED;
 		}
 		t = n;
 	}
 }
 
 static void remove_expired_notes(presentity_t *_p)
 {
 	pa_presence_note_t *n, *nn;
 
 	n = (pa_presence_note_t*)_p->data.first_note;
 	while (n) {
 		nn = (pa_presence_note_t *)n->data.next;
 		if (n->expires < act_time) {
 			DBG("Expiring note %.*s\n", FMT_STR(n->data.value));
 			remove_pres_note(_p, n);
 			_p->flags |= PFLAG_PRESENCE_CHANGED;
 		}
 		n = nn;
 	}
 }
 
018409d0
 static void remove_expired_extension_elements(presentity_t *_p)
5d58dfb2
 {
018409d0
 	pa_extension_element_t *n, *nn;
5d58dfb2
 
018409d0
 	n = (pa_extension_element_t *)_p->data.first_unknown_element;
5d58dfb2
 	while (n) {
018409d0
 		nn = (pa_extension_element_t *)n->data.next;
5d58dfb2
 		if (n->expires < act_time) {
018409d0
 			DBG("Expiring person element %.*s\n", FMT_STR(n->dbid));
 			remove_extension_element(_p, n);
5d58dfb2
 			_p->flags |= PFLAG_PRESENCE_CHANGED;
 		}
 		n = nn;
 	}
 }
 
 static inline int refresh_auth_rules(presentity_t *p)
 {
 	/* TODO reload authorization rules if needed */
 	if ((p->auth_rules_refresh_time > 0) && 
 			(p->auth_rules_refresh_time <= act_time)) {
 /*		INFO("refreshing auth rules\n"); */
 		ask_auth_rules(p); /* it will run next time if fails now */
 		p->auth_rules_refresh_time = act_time + auth_rules_refresh_time;
 	}
 	return 0;
 }
 
 static void process_tuple_change(presentity_t *p, tuple_change_info_t *info)
 {
 	presence_tuple_t *tuple = NULL;
018409d0
 	basic_tuple_status_t orig;
5d58dfb2
 	time_t e;
 
 	DBG("processing tuple change message: %.*s, %.*s, %d\n",
 			FMT_STR(info->user), FMT_STR(info->contact), info->state);
 
 	if (is_str_empty(&info->contact)) {
 		/* error - registered tuples need contact address */
 		ERR("invalid registered tuple (empty contact)\n");
 		return;
 	}
 	
 	if (info->state == presence_tuple_closed) {
 		e = act_time + 2 * timer_interval;
 	}
 	else {
 		e = INT_MAX; /* act_time + default_expires; */
 		/* hack - re-registrations don't call the callback */
 	}
 	
 	/* Find only registered (not published) tuple - don't overwrite
 	 * published information! */
 	if (find_registered_presence_tuple(&info->contact, p, &tuple) != 0) {
 		/* not found -> create new tuple */
 		new_presence_tuple(&info->contact, e, &tuple, 0, NULL, NULL, NULL);
 		if (!tuple) return; /* error */
 		
018409d0
 		tuple->data.status.basic = info->state;
5d58dfb2
 		add_presence_tuple(p, tuple);
 		p->flags |= PFLAG_PRESENCE_CHANGED;
 	}
 	else {
 		/* tuple found -> update */
018409d0
 		orig = tuple->data.status.basic;
 		tuple->data.status.basic = info->state;
5d58dfb2
 		tuple->expires = e;
 		db_update_presence_tuple(p, tuple, 0);
 			
018409d0
 		if (orig != tuple->data.status.basic) p->flags |= PFLAG_PRESENCE_CHANGED;
5d58dfb2
 	}
 }
 
 static int process_qsa_message(presentity_t *p, client_notify_info_t *info)
 {
 	TRACE("received QSA notification for presentity %.*s\n", FMT_STR(p->data.uri));
 
 	/* TODO: handle it as publish for special tuple (but handle merging 
 	 * from multiple QSA sources in any way) */
 	
 	return 0;
 }
 
 static void process_presentity_messages(presentity_t *p)
 {
 	mq_message_t *msg;
 	tuple_change_info_t *info;
 	client_notify_info_t *qsa_info;
 
 	while ((msg = pop_message(&p->mq)) != NULL) {
 
 		/* FIXME: ugly data type detection */
 		if (msg->destroy_function == (destroy_function_f)free_tuple_change_info_content) {
 			info = (tuple_change_info_t*)get_message_data(msg);
 			if (info) process_tuple_change(p, info);
 		}
 		else {
 			/* QSA message */
 			qsa_info = (client_notify_info_t *)get_message_data(msg);
 			if (qsa_info) process_qsa_message(p, qsa_info);
 		}
 			
 		free_message(msg);
 	}
 }
 
 
 int timer_presentity(presentity_t* _p)
 {
 	int old_flags;
 	int presentity_changed;
 
 	PROF_START(pa_timer_presentity)
 	old_flags = _p->flags;
 
 	/* reload authorization rules if needed */
 	refresh_auth_rules(_p);
 	
 	process_presentity_messages(_p);
 	
 	remove_expired_tuples(_p, NULL);
 	
 	remove_expired_notes(_p);
018409d0
 	remove_expired_extension_elements(_p);
5d58dfb2
 	
 	/* notify watchers and remove expired */
 	process_watchers(_p, NULL);	
 	/* notify winfo watchers and remove expired */
 	process_winfo_watchers(_p, NULL); 
 	
 	/* notify internal watchers */
 	presentity_changed = _p->flags & PFLAG_PRESENCE_CHANGED;
 	if (presentity_changed) {
 		/* DBG("presentity %.*s changed\n", _p->uri.len, _p->uri.s); */
 		notify_qsa_watchers(_p);
 	}
 
 	/* clear presentity "change" flags */
 	_p->flags &= ~(PFLAG_PRESENCE_CHANGED | PFLAG_WATCHERINFO_CHANGED);
 	
 	/* update DB record if something changed - USELESS */
 /*	if (changed) {
 		db_update_presentity(_p);
 	} 
 */	
 	PROF_STOP(pa_timer_presentity)
 	return 0;
 }