00001 #include "presentity.h"
00002 #include "pa_mod.h"
00003 #include "ptime.h"
00004 #include "notify.h"
00005 #include "async_auth.h"
00006 #include "tuple.h"
00007 #include "pres_notes.h"
00008 #include "extension_elements.h"
00009
00010 static void process_watchers(presentity_t* _p, int *changed)
00011 {
00012 watcher_t *next, *w;
00013 int presentity_changed;
00014 int notify;
00015
00016
00017
00018
00019 presentity_changed = _p->flags & PFLAG_PRESENCE_CHANGED;
00020
00021 w = _p->first_watcher;
00022 while (w) {
00023
00024 if (w->expires <= act_time) {
00025 LOG(L_DBG, "Expired watcher %.*s\n", w->uri.len, w->uri.s);
00026 w->expires = 0;
00027 set_watcher_terminated_status(w);
00028 _p->flags |= PFLAG_WATCHERINFO_CHANGED;
00029 w->flags |= WFLAG_SUBSCRIPTION_CHANGED;
00030 if (changed) *changed = 1;
00031 }
00032
00033
00034 notify = 0;
00035 if ((w->flags & WFLAG_SUBSCRIPTION_CHANGED)) {
00036 notify = 1;
00037 if (changed) *changed = 1;
00038 }
00039 if (presentity_changed && is_watcher_authorized(w)) notify = 1;
00040 if (notify) send_notify(_p, w);
00041 w->flags &= ~WFLAG_SUBSCRIPTION_CHANGED;
00042
00043 if (is_watcher_terminated(w)) {
00044 next = w->next;
00045 remove_watcher(_p, w);
00046 free_watcher(w);
00047 w = next;
00048 if (changed) *changed = 1;
00049 }
00050 else w = w->next;
00051 }
00052 }
00053
00054 static void process_winfo_watchers(presentity_t* _p, int *changed)
00055 {
00056 watcher_t *next, *w;
00057 int notify;
00058
00059
00060
00061
00062 w = _p->first_winfo_watcher;
00063 while (w) {
00064
00065 if (w->expires <= act_time) {
00066 LOG(L_DBG, "Expired watcher %.*s\n", w->uri.len, w->uri.s);
00067 w->expires = 0;
00068 set_watcher_terminated_status(w);
00069 w->flags |= WFLAG_SUBSCRIPTION_CHANGED;
00070 if (changed) *changed = 1;
00071 }
00072
00073
00074 notify = 0;
00075 if ((w->flags & WFLAG_SUBSCRIPTION_CHANGED)) {
00076 notify = 1;
00077 if (changed) *changed = 1;
00078 }
00079 if ((_p->flags & PFLAG_WATCHERINFO_CHANGED) &&
00080 is_watcher_authorized(w)) notify = 1;
00081 if (notify) send_notify(_p, w);
00082 w->flags &= ~WFLAG_SUBSCRIPTION_CHANGED;
00083
00084 if (is_watcher_terminated(w)) {
00085 next = w->next;
00086 remove_watcher(_p, w);
00087 free_watcher(w);
00088 w = next;
00089 if (changed) *changed = 1;
00090 }
00091 else w = w->next;
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 static void remove_expired_tuples(presentity_t *_p, int *changed)
00111 {
00112 presence_tuple_t *t, *n;
00113
00114 t = (presence_tuple_t*)_p->data.first_tuple;
00115 while (t) {
00116 n = (presence_tuple_t *)t->data.next;
00117 if (t->expires < act_time) {
00118 DBG("Expiring tuple %.*s\n", t->data.contact.len, t->data.contact.s);
00119 remove_presence_tuple(_p, t);
00120 free_presence_tuple(t);
00121 if (changed) *changed = 1;
00122 _p->flags |= PFLAG_PRESENCE_CHANGED;
00123 }
00124 t = n;
00125 }
00126 }
00127
00128 static void remove_expired_notes(presentity_t *_p)
00129 {
00130 pa_presence_note_t *n, *nn;
00131
00132 n = (pa_presence_note_t*)_p->data.first_note;
00133 while (n) {
00134 nn = (pa_presence_note_t *)n->data.next;
00135 if (n->expires < act_time) {
00136 DBG("Expiring note %.*s\n", FMT_STR(n->data.value));
00137 remove_pres_note(_p, n);
00138 _p->flags |= PFLAG_PRESENCE_CHANGED;
00139 }
00140 n = nn;
00141 }
00142 }
00143
00144 static void remove_expired_extension_elements(presentity_t *_p)
00145 {
00146 pa_extension_element_t *n, *nn;
00147
00148 n = (pa_extension_element_t *)_p->data.first_unknown_element;
00149 while (n) {
00150 nn = (pa_extension_element_t *)n->data.next;
00151 if (n->expires < act_time) {
00152 DBG("Expiring person element %.*s\n", FMT_STR(n->dbid));
00153 remove_extension_element(_p, n);
00154 _p->flags |= PFLAG_PRESENCE_CHANGED;
00155 }
00156 n = nn;
00157 }
00158 }
00159
00160 static inline int refresh_auth_rules(presentity_t *p)
00161 {
00162
00163 if ((p->auth_rules_refresh_time > 0) &&
00164 (p->auth_rules_refresh_time <= act_time)) {
00165
00166 ask_auth_rules(p);
00167 p->auth_rules_refresh_time = act_time + auth_rules_refresh_time;
00168 }
00169 return 0;
00170 }
00171
00172 static void process_tuple_change(presentity_t *p, tuple_change_info_t *info)
00173 {
00174 presence_tuple_t *tuple = NULL;
00175 basic_tuple_status_t orig;
00176 time_t e;
00177
00178 DBG("processing tuple change message: %.*s, %.*s, %d\n",
00179 FMT_STR(info->user), FMT_STR(info->contact), info->state);
00180
00181 if (is_str_empty(&info->contact)) {
00182
00183 ERR("invalid registered tuple (empty contact)\n");
00184 return;
00185 }
00186
00187 if (info->state == presence_tuple_closed) {
00188 e = act_time + 2 * timer_interval;
00189 }
00190 else {
00191 e = INT_MAX;
00192
00193 }
00194
00195
00196
00197 if (find_registered_presence_tuple(&info->contact, p, &tuple) != 0) {
00198
00199 new_presence_tuple(&info->contact, e, &tuple, 0, NULL, NULL, NULL);
00200 if (!tuple) return;
00201
00202 tuple->data.status.basic = info->state;
00203 add_presence_tuple(p, tuple);
00204 p->flags |= PFLAG_PRESENCE_CHANGED;
00205 }
00206 else {
00207
00208 orig = tuple->data.status.basic;
00209 tuple->data.status.basic = info->state;
00210 tuple->expires = e;
00211 db_update_presence_tuple(p, tuple, 0);
00212
00213 if (orig != tuple->data.status.basic) p->flags |= PFLAG_PRESENCE_CHANGED;
00214 }
00215 }
00216
00217 static int process_qsa_message(presentity_t *p, client_notify_info_t *info)
00218 {
00219 TRACE("received QSA notification for presentity %.*s\n", FMT_STR(p->data.uri));
00220
00221
00222
00223
00224 return 0;
00225 }
00226
00227 static void process_presentity_messages(presentity_t *p)
00228 {
00229 mq_message_t *msg;
00230 tuple_change_info_t *info;
00231 client_notify_info_t *qsa_info;
00232
00233 while ((msg = pop_message(&p->mq)) != NULL) {
00234
00235
00236 if (msg->destroy_function == (destroy_function_f)free_tuple_change_info_content) {
00237 info = (tuple_change_info_t*)get_message_data(msg);
00238 if (info) process_tuple_change(p, info);
00239 }
00240 else {
00241
00242 qsa_info = (client_notify_info_t *)get_message_data(msg);
00243 if (qsa_info) process_qsa_message(p, qsa_info);
00244 }
00245
00246 free_message(msg);
00247 }
00248 }
00249
00250
00251 int timer_presentity(presentity_t* _p)
00252 {
00253 int old_flags;
00254 int presentity_changed;
00255
00256 PROF_START(pa_timer_presentity)
00257 old_flags = _p->flags;
00258
00259
00260 refresh_auth_rules(_p);
00261
00262 process_presentity_messages(_p);
00263
00264 remove_expired_tuples(_p, NULL);
00265
00266 remove_expired_notes(_p);
00267 remove_expired_extension_elements(_p);
00268
00269
00270 process_watchers(_p, NULL);
00271
00272 process_winfo_watchers(_p, NULL);
00273
00274
00275 presentity_changed = _p->flags & PFLAG_PRESENCE_CHANGED;
00276 if (presentity_changed) {
00277
00278 notify_qsa_watchers(_p);
00279 }
00280
00281
00282 _p->flags &= ~(PFLAG_PRESENCE_CHANGED | PFLAG_WATCHERINFO_CHANGED);
00283
00284
00285
00286
00287
00288
00289 PROF_STOP(pa_timer_presentity)
00290 return 0;
00291 }