123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- #include "presentity.h"
- #include "pa_mod.h"
- #include "ptime.h"
- #include "notify.h"
- #include "async_auth.h"
- #include "tuple.h"
- #include "pres_notes.h"
- #include "extension_elements.h"
- 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;
- }
- }
- static void remove_expired_extension_elements(presentity_t *_p)
- {
- pa_extension_element_t *n, *nn;
- n = (pa_extension_element_t *)_p->data.first_unknown_element;
- while (n) {
- nn = (pa_extension_element_t *)n->data.next;
- if (n->expires < act_time) {
- DBG("Expiring person element %.*s\n", FMT_STR(n->dbid));
- remove_extension_element(_p, n);
- _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;
- basic_tuple_status_t orig;
- 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 */
-
- tuple->data.status.basic = info->state;
- add_presence_tuple(p, tuple);
- p->flags |= PFLAG_PRESENCE_CHANGED;
- }
- else {
- /* tuple found -> update */
- orig = tuple->data.status.basic;
- tuple->data.status.basic = info->state;
- tuple->expires = e;
- db_update_presence_tuple(p, tuple, 0);
-
- if (orig != tuple->data.status.basic) p->flags |= PFLAG_PRESENCE_CHANGED;
- }
- }
- 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);
- remove_expired_extension_elements(_p);
-
- /* 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;
- }
|