presence: implemented more functions to work with in-memory presentity records
authorDaniel-Constantin Mierla <miconda@gmail.com>
Wed, 22 Apr 2020 19:01:38 +0000 (21:01 +0200)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Wed, 22 Apr 2020 19:02:50 +0000 (21:02 +0200)
src/modules/presence/hash.c
src/modules/presence/hash.h
src/modules/presence/notify.c
src/modules/presence/presentity.c

index dc36d0b..9c81b7b 100644 (file)
@@ -1238,7 +1238,7 @@ ps_presentity_t *ps_ptable_get_list(str *user, str *domain)
 /**
  *
  */
-ps_presentity_t *ps_ptable_search(ps_presentity_t *ptm, int rmode)
+ps_presentity_t *ps_ptable_search(ps_presentity_t *ptm, int mmode, int rmode)
 {
        ps_presentity_t *ptn = NULL;
        ps_presentity_t *ptl = NULL;
@@ -1253,7 +1253,7 @@ ps_presentity_t *ps_ptable_search(ps_presentity_t *ptm, int rmode)
        lock_get(&_ps_ptable->slots[idx].lock);
        ptn = _ps_ptable->slots[idx].plist;
        while(ptn!=NULL) {
-               if((ps_presentity_match(ptn, ptm, 1)==1)
+               if((ps_presentity_match(ptn, ptm, mmode)==1)
                                && (ptm->expires==0 || ptn->expires > ptm->expires)) {
                        ptd = ps_presentity_dup(ptn, 1);
                        if(ptd == NULL) {
index 1b2e96e..262d7f6 100644 (file)
@@ -181,7 +181,7 @@ int ps_ptable_update(ps_presentity_t *ptm, ps_presentity_t *pt);
 int ps_ptable_remove(ps_presentity_t *pt);
 ps_presentity_t *ps_ptable_get_list(str *user, str *domain);
 ps_presentity_t *ps_ptable_get_item(str *user, str *domain, str *event, str *etag);
-ps_presentity_t *ps_ptable_search(ps_presentity_t *ptm, int rmode);
+ps_presentity_t *ps_ptable_search(ps_presentity_t *ptm, int mmode, int rmode);
 ps_presentity_t *ps_ptable_get_expired(int eval);
 ps_ptable_t *ps_ptable_get(void);
 
index f221745..87ed58c 100644 (file)
@@ -891,7 +891,7 @@ str *ps_cache_get_p_notify_body(str pres_uri, pres_ev_t *event, str *etag,
                ptm.expires = (int)time(NULL);
        }
 
-       ptlist = ps_ptable_search(&ptm, pres_retrieve_order);
+       ptlist = ps_ptable_search(&ptm, 1, pres_retrieve_order);
 
        if(ptlist == NULL) {
                LM_DBG("the query returned no result\n[username]= %.*s"
index c17dbbe..bc17bf1 100644 (file)
@@ -343,7 +343,7 @@ done:
        return rmatch;
 }
 
-int delete_presentity_if_dialog_id_exists(
+int ps_db_delete_presentity_if_dialog_id_exists(
                presentity_t *presentity, char *dialog_id)
 {
        db_key_t query_cols[13], result_cols[6];
@@ -451,10 +451,74 @@ int delete_presentity_if_dialog_id_exists(
        return 0;
 }
 
+int ps_cache_delete_presentity_if_dialog_id_exists(
+               presentity_t *presentity, char *dialog_id)
+{
+       char *db_dialog_id = NULL;
+       int db_is_dialog = 0;
+       presentity_t old_presentity;
+       ps_presentity_t ptm;
+       ps_presentity_t *ptx = NULL;
+       ps_presentity_t *ptlist = NULL;
+
+       if(presentity->event->evp->type != EVENT_DIALOG) {
+               return 0;
+       }
+       memset(&ptm, 0, sizeof(ps_presentity_t));
+
+       ptm.user = presentity->user;
+       ptm.domain = presentity->domain;
+       ptm.event = presentity->event->name;
+
+       ptlist = ps_ptable_search(&ptm, 1, 0);
+
+       if(ptlist == NULL) {
+               return 0;
+       }
+
+       for(ptx=ptlist; ptx!=NULL; ptx=ptx->next) {
+               if(check_if_dialog(ptx->body, &db_is_dialog, &db_dialog_id) == 0) {
+                       // If ID from DB matches the one we supplied
+                       if(db_dialog_id && !strcmp(db_dialog_id, dialog_id)) {
+                               old_presentity.domain = presentity->domain;
+                               old_presentity.user = presentity->user;
+                               old_presentity.event = presentity->event;
+                               old_presentity.etag = ptx->etag;
+
+                               LM_DBG("Presentity found - deleting it\n");
+
+                               if(delete_presentity(&old_presentity, NULL) < 0) {
+                                       LM_ERR("failed to delete presentity\n");
+                               }
+                               ps_presentity_list_free(ptlist, 1);
+                               free(db_dialog_id);
+                               db_dialog_id = NULL;
+                               return 1;
+                       }
+                       free(db_dialog_id);
+                       db_dialog_id = NULL;
+               }
+       }
+       ps_presentity_list_free(ptlist, 1);
+       return 0;
+}
+
+int delete_presentity_if_dialog_id_exists(
+               presentity_t *presentity, char *dialog_id)
+{
+       if(publ_cache_mode == PS_PCACHE_RECORD) {
+               return ps_cache_delete_presentity_if_dialog_id_exists(presentity,
+                               dialog_id);
+       } else {
+               return ps_db_delete_presentity_if_dialog_id_exists(presentity,
+                               dialog_id);
+       }
+}
+
 /**
- * check if the states of all related dialogs match vstate
+ *
  */
-int ps_match_dialog_state(presentity_t *presentity, char *vstate)
+int ps_db_match_dialog_state(presentity_t *presentity, char *vstate)
 {
        db_key_t query_cols[13], result_cols[6];
        db_op_t query_ops[13];
@@ -543,6 +607,56 @@ int ps_match_dialog_state(presentity_t *presentity, char *vstate)
        return rmatch;
 }
 
+/**
+ *
+ */
+int ps_cache_match_dialog_state(presentity_t *presentity, char *vstate)
+{
+       int db_is_dialog = 0;
+       int rmatch = 0;
+       ps_presentity_t *ptx = NULL;
+       ps_presentity_t *ptlist = NULL;
+       ps_presentity_t ptm;
+
+       memset(&ptm, 0, sizeof(ps_presentity_t));
+
+       ptm.user = presentity->user;
+       ptm.domain = presentity->domain;
+       ptm.event = presentity->event->name;
+       ptm.etag = presentity->etag;
+
+       ptlist = ps_ptable_search(&ptm, 2, 0);
+
+       if(ptlist==NULL) {
+               return 0;
+       }
+
+       for(ptx=ptlist; ptx!=NULL; ptx=ptx->next) {
+               rmatch = ps_match_dialog_state_from_body(ptx->body, &db_is_dialog, vstate);
+
+               if(rmatch == 1) {
+                       /* having a full match */
+                       ps_presentity_list_free(ptlist, 1);
+                       return rmatch;
+               }
+       }
+
+       ps_presentity_list_free(ptlist, 1);
+       return rmatch;
+}
+
+/**
+ * check if the states of all related dialogs match vstate
+ */
+int ps_match_dialog_state(presentity_t *presentity, char *vstate)
+{
+       if(publ_cache_mode == PS_PCACHE_RECORD) {
+               return ps_cache_match_dialog_state(presentity, vstate);
+       } else {
+               return ps_db_match_dialog_state(presentity, vstate);
+       }
+}
+
 static int ps_db_update_presentity(sip_msg_t *msg, presentity_t *presentity,
                str *body, int new_t, int *sent_reply, char *sphere, str *etag_override,
                str *ruid, int replace)
@@ -1900,7 +2014,6 @@ error:
 
 char *extract_sphere(str *body)
 {
-
        /* check for a rpid sphere element */
        xmlDocPtr doc = NULL;
        xmlNodePtr node;
@@ -1963,7 +2076,7 @@ xmlNodePtr xmlNodeGetNodeByName(
        return NULL;
 }
 
-char *get_sphere(str *pres_uri)
+char *ps_db_get_sphere(str *pres_uri)
 {
        unsigned int hash_code;
        char *sphere = NULL;
@@ -2089,6 +2202,60 @@ error:
        return NULL;
 }
 
+char *ps_cache_get_sphere(str *pres_uri)
+{
+       char *sphere = NULL;
+       sip_uri_t uri;
+       ps_presentity_t ptm;
+       ps_presentity_t *ptx = NULL;
+       ps_presentity_t *ptlist = NULL;
+
+       if(!pres_sphere_enable) {
+               return NULL;
+       }
+
+       if(parse_uri(pres_uri->s, pres_uri->len, &uri) < 0) {
+               LM_ERR("failed to parse presentity uri\n");
+               return NULL;
+       }
+
+       memset(&ptm, 0, sizeof(ps_presentity_t));
+
+       ptm.user = uri.user;
+       ptm.domain = uri.host;
+       ptm.event.s = "presence";
+       ptm.event.len = 8;
+
+       ptlist = ps_ptable_search(&ptm, 1, pres_retrieve_order);
+
+       if(ptlist == NULL) {
+               return NULL;
+       }
+       ptx = ptlist;
+       while(ptx->next) {
+               ptx = ptx->next;
+       }
+
+       if(ptx->body.s==NULL || ptx->body.len<=0) {
+               ps_presentity_list_free(ptlist, 1);
+               return NULL;
+       }
+
+       sphere = extract_sphere(&ptx->body);
+       ps_presentity_list_free(ptlist, 1);
+
+       return sphere;
+}
+
+char *get_sphere(str *pres_uri)
+{
+       if(publ_cache_mode == PS_PCACHE_RECORD) {
+               return ps_cache_get_sphere(pres_uri);
+       } else {
+               return ps_db_get_sphere(pres_uri);
+       }
+}
+
 int mark_presentity_for_delete(presentity_t *pres, str *ruid)
 {
        db_key_t query_cols[4], result_cols[1], update_cols[3];
@@ -2109,6 +2276,11 @@ int mark_presentity_for_delete(presentity_t *pres, str *ruid)
                goto done;
        }
 
+       if(pa_db==NULL) {
+               LM_ERR("no database connection setup\n");
+               goto error;
+       }
+
        if(pa_dbf.use_table(pa_db, &presentity_table) < 0) {
                LM_ERR("unsuccessful use table sql operation\n");
                goto error;
@@ -2339,6 +2511,11 @@ int delete_offline_presentities(str *pres_uri, pres_ev_t *event)
        int n_query_cols = 0;
        struct sip_uri uri;
 
+       if(pa_db==NULL) {
+               LM_ERR("no database connection setup\n");
+               goto error;
+       }
+
        if(parse_uri(pres_uri->s, pres_uri->len, &uri) < 0) {
                LM_ERR("failed to parse presentity uri\n");
                goto error;