obsolete/pa/qsa_interface.c
541e1786
 #include "qsa_interface.h"
 #include "pdomain.h"
 #include "pa_mod.h"
 #include "dlist.h"
 #include "auth.h"
 
 #include <presence/qsa.h>
 #include <presence/notifier.h>
 #include <cds/logger.h>
 #include <cds/memory.h>
 #include <cds/list.h>
 #include <presence/pres_doc.h>
 
 static notifier_domain_t *domain = NULL;
 static notifier_t *notifier = NULL;
 
3f4b99d7
 static qsa_content_type_t *ct_presence_info = NULL;
 /*static qsa_content_type_t *ct_pidf_xml = NULL;*/
 
279cad71
 /* static str_t notifier_name = { s: "pa", len: 2 }; */
541e1786
 
33364921
 static int pa_subscribe(notifier_t *n, qsa_subscription_t *subscription);
 static void pa_unsubscribe(notifier_t *n, qsa_subscription_t *subscription);
541e1786
 
 extern dlist_t* root; /* ugly !!!!! */
 
2b99b5e5
 int accept_internal_subscriptions = 0;
541e1786
 
 /* QSA interface initialization */
 int pa_qsa_interface_init()
 {
3f4b99d7
 	static str presence_info = STR_STATIC_INIT(CT_PRESENCE_INFO);
 	static str_t presence_package = { s: "presence", len: 8 };
 	
541e1786
 	domain = qsa_get_default_domain();
 	if (!domain) {
e5dd5e9c
 		ERR("can't register notifier domain\n");
541e1786
 		return -1;	
 	}
e5dd5e9c
 	/* DBG("QSA (pa) domain: %p\n", domain); */
541e1786
 
 	notifier = register_notifier(domain, &presence_package, 
 			pa_subscribe, pa_unsubscribe, NULL);
 	if (!notifier) {
e5dd5e9c
 		ERR("can't register notifier\n");
541e1786
 		return -1;	
 	}
3f4b99d7
 	
 	ct_presence_info = register_content_type(domain, 
 			&presence_info, (destroy_function_f)free_presentity_info);
 	if (!ct_presence_info) {
 		ERR("can't register QSA content type\n");
 		return -1;
 	}
 	else TRACE("PA_CONTENT_TYPE: %p\n", ct_presence_info);
 	
e5dd5e9c
 	/* DBG("pa_qsa_interface_init(): created notifier %.*s\n", FMT_STR(notifier_name)); */
541e1786
 	return 0;
 }
 
 void pa_qsa_interface_destroy()
 {
284e5638
 	if (domain && notifier) unregister_notifier(domain, notifier);
e7d99a09
 	notifier = NULL;
 	/* no new qsa subscriptions will be created now - now can be
 	 * released all existing ones */
 	
ef3076de
 	if (domain) qsa_release_domain(domain);
e7d99a09
 	/* no QSA operations should be done there (don't send 
 	 * notification messages, ...) only subscriptions may
 	 * be released */
 	domain = NULL;
541e1786
 }
 
 /* notifier functions */
 
 static int add_internal_subscription(presentity_t *p, internal_pa_subscription_t *is)
 {
 	if (is->status != WS_ACTIVE) 
 		is->status = authorize_internal_watcher(p, is);
 	if (is->status == WS_REJECTED) return -1;
 	DOUBLE_LINKED_LIST_ADD(p->first_qsa_subscription, 
 			p->last_qsa_subscription, is);
 
 	return 0;
 }
 
33364921
 internal_pa_subscription_t *create_internal_subscription(qsa_subscription_t *s)
541e1786
 {
 	internal_pa_subscription_t *ss = cds_malloc(sizeof(internal_pa_subscription_t));
 	if (!ss) return ss;
 	ss->subscription = s;
 	ss->status = WS_PENDING;
 	ss->prev = NULL;
 	ss->next = NULL;
 	return ss;
 }
 
 void free_internal_subscription(internal_pa_subscription_t *is)
 {
 	if (is) cds_free(is);
 }
 		
33364921
 static int pa_subscribe(notifier_t *n, qsa_subscription_t *subscription)
541e1786
 {
 	dlist_t *dl;
 	presentity_t *p = NULL;
 	internal_pa_subscription_t *ss;
19ef0e8f
 	str uid = STR_NULL;
33364921
 	str *record_id = NULL;
f7372307
 	xcap_query_params_t xcap_params;
541e1786
 	
2b99b5e5
 	if (!accept_internal_subscriptions) return 0; /* do not accept subscriptions */
 	
33364921
 	record_id = get_record_id(subscription);
 	if (!record_id) {
 		ERR("BUG: subscription to empty record\n");
 		return -1;
 	}
 	
e5dd5e9c
 	DBG("SUBSCRIBE to PA for %.*s [%.*s]\n", 
33364921
 			FMT_STR(*record_id),
541e1786
 			FMT_STR(subscription->package->name));
 
33364921
 	if (pres_uri2uid(&uid, record_id) != 0) {
19ef0e8f
 		/* can't convert uri to uid */
49bc49e2
 		INFO("can't convert URI to UID for internal PA subscription\n");
19ef0e8f
 		return -1;
 	}
e5dd5e9c
 
 	/* DBG("SUBSCRIBE to uid: %.*s\n", FMT_STR(uid)); */
19ef0e8f
 	
541e1786
 	dl = root;	/* FIXME: ugly and possibly unsafe (locking needed?) */
 	while (dl) {
 		/* create new server subscription */
 		ss = create_internal_subscription(subscription);
 		if (!ss) {
 			ERROR_LOG("can't allocate memory for internal pa subscription\n");
 			break;
 		}
 		
 		lock_pdomain(dl->d);	
19ef0e8f
 		if (find_presentity_uid(dl->d, &uid, &p) != 0) p = NULL;
541e1786
 		if (!p) {
f7372307
 			memset(&xcap_params, 0, sizeof(xcap_params));
 			if (fill_xcap_params) fill_xcap_params(NULL, &xcap_params);
 			if (new_presentity(dl->d, record_id, &uid, &xcap_params, &p) < 0) {
e5dd5e9c
 				ERR("can't create presentity\n");
541e1786
 			}
 		}
 		if (p) {
 			/* add server subscription to p */
 			if (add_internal_subscription(p, ss) == 0) {
c0e3df65
 				p->flags |= PFLAG_WATCHERINFO_CHANGED;
 				notify_internal_watcher(p, ss);
541e1786
 			}
 			else {
 				/* error adding subscription to p (auth failed, ...) */
 				free_internal_subscription(ss);
 			}
 		}
 		unlock_pdomain(dl->d);
 		dl = dl->next;
 	}
19ef0e8f
 
 	str_free_content(&uid);
e5dd5e9c
 	DBG("finished SUBSCRIBE to PA for %.*s [%.*s]\n", 
33364921
 			FMT_STR(*record_id),
e5dd5e9c
 			FMT_STR(subscription->package->name));
19ef0e8f
 	
541e1786
 	return 0;
 }
 
33364921
 static void remove_internal_subscription(presentity_t *p, qsa_subscription_t *s)
541e1786
 {	
 	internal_pa_subscription_t *ss;
 	ss = p->first_qsa_subscription;
 	while (ss) {
 		if (s == ss->subscription) {
 			DOUBLE_LINKED_LIST_REMOVE(p->first_qsa_subscription, p->last_qsa_subscription, ss);
 			free_internal_subscription(ss);
 			break; /* may be only once */
 		}
 		ss = ss->next;
 	}
 }
 
33364921
 static void pa_unsubscribe(notifier_t *n, qsa_subscription_t *subscription)
541e1786
 {
 	dlist_t *dl;
 	presentity_t *p = NULL;
19ef0e8f
 	str uid = STR_NULL;
33364921
 	str *record_id = NULL;
19ef0e8f
 	
2b99b5e5
 	if (!accept_internal_subscriptions) return; /* do not accept subscriptions */
 	
33364921
 	record_id = get_record_id(subscription);
 	if (!record_id) {
 		ERR("BUG: unsubscription to empty record\n");
 		return;
 	}
 	
 	if (pres_uri2uid(&uid, record_id) != 0) {
19ef0e8f
 		/* can't convert uri to uid */
e5dd5e9c
 		ERR("can't convert URI to UID for internal PA unsubscription\n");
19ef0e8f
 		return;
 	}
541e1786
 	
e5dd5e9c
 	/* DBG("UNBSCRIBE from PA for %.*s [%.*s]\n", 
541e1786
 			FMT_STR(subscription->record_id),
284e5638
 			FMT_STR(subscription->package->name)); */
541e1786
 
 	dl = root;	/* FIXME: ugly and possibly unsafe (locking needed?) */
 	while (dl) {
 		lock_pdomain(dl->d);	
19ef0e8f
 		if (find_presentity_uid(dl->d, &uid, &p) != 0) p = NULL;
541e1786
 		if (!p) continue;
 			
 		remove_internal_subscription(p, subscription);
4ed1023f
 		p->flags |= PFLAG_WATCHERINFO_CHANGED;
541e1786
 		
 		unlock_pdomain(dl->d);
 		dl = dl->next;
 	}
19ef0e8f
 	str_free_content(&uid);
541e1786
 }
 
 int notify_internal_watcher(presentity_t *p, internal_pa_subscription_t *ss)
 {
 	presentity_info_t *pinfo;
c0e3df65
 
 	/* notify only accepted watchers */
d55f0229
 	switch (ss->status) {
 		case WS_PENDING:
 				return notify_subscriber(ss->subscription, notifier, 
3f4b99d7
 							ct_presence_info, NULL, qsa_subscription_pending);
d55f0229
 		case WS_REJECTED:
 				return notify_subscriber(ss->subscription, notifier, 
3f4b99d7
 							ct_presence_info, NULL, qsa_subscription_rejected);
d55f0229
 
 		case WS_PENDING_TERMINATED:
 		case WS_TERMINATED:
 				return notify_subscriber(ss->subscription, notifier,
3f4b99d7
 							ct_presence_info, NULL, qsa_subscription_terminated);
d55f0229
 		case WS_ACTIVE:
5d58dfb2
 				pinfo = dup_presentity_info(&p->data);
d55f0229
 				if (!pinfo) {
 					ERROR_LOG("can't create presentity info from presentity!\n");
 					return -1; 
 				}
 				
 				return notify_subscriber(ss->subscription, notifier, 
3f4b99d7
 						ct_presence_info, pinfo, qsa_subscription_active);
541e1786
 	}
d55f0229
 
 	return 0;
541e1786
 }
 	
 int notify_qsa_watchers(presentity_t *p)
 {
 	internal_pa_subscription_t *ss;
 	int res = 0;
 	
e5dd5e9c
 	/* DBG("notify_qsa_watchers for %.*s\n", FMT_STR(p->uri)); */
541e1786
 	ss = p->first_qsa_subscription;
 	while (ss) {
c0e3df65
 		if (notify_internal_watcher(p, ss) < 0) res = -1;
541e1786
 		ss = ss->next;
 	}
 	return res;
 }
 
1b1ffb43
 int subscribe_to_user(presentity_t *_p)
 {
 	static str package = STR_STATIC_INIT("presence");
 	
 	clear_subscription_data(&_p->presence_subscription_data);
 	/* ??? FIXME msg queue */ _p->presence_subscription_data.dst = &_p->mq;
5d58dfb2
 	_p->presence_subscription_data.record_id = _p->data.uri;
1b1ffb43
 	_p->presence_subscription_data.subscriber_id = pa_subscription_uri;
 	_p->presence_subscription_data.subscriber_data = _p;
 	_p->presence_subscription = subscribe(domain, 
 			&package, &_p->presence_subscription_data);
 
 	if (_p->presence_subscription) return 0;
 	else return -1;
 }
 
 int unsubscribe_to_user(presentity_t *_p)
 {
 	unsubscribe(domain, _p->presence_subscription);
 	/* TODO ? clean messages ? they will be freed automaticaly ... */
 	return 0;
 }