Jelajahi Sumber

Merge pull request #1016 from lazedo/presence-has-subscribers-master

presence: add pres_has_subscribers
Daniel-Constantin Mierla 8 tahun lalu
induk
melakukan
3d19bea766

+ 21 - 0
src/modules/presence/doc/presence_admin.xml

@@ -1024,6 +1024,27 @@ if (method=="MESSAGE") {
 		</example>
 	</section>
 
+<section id="presence.f.pres_has_subscribers">
+    <title>
+        <function moreinfo="none">pres_has_subscribers(presentity_uri, event)</function>
+    </title>
+    <para>
+        Allows to check if presentity has any subscribers of event.
+    </para>
+    <para>
+        This function can be used from ANY_ROUTE.
+    </para>
+    <example>
+        <title><function>pres_has_subscribers</function> usage</title>
+        <programlisting format="linespecific">
+            ...
+            if(pres_has_subscribers($var(uri), "message-summary"))
+            do something...;
+            ...
+        </programlisting>
+    </example>
+</section>
+
 	<section id="presence.f.pres_refresh_watchers">
 		<title>
 		<function moreinfo="none">pres_refresh_watchers(uri, event, type[, file_uri, filename])</function>

+ 43 - 1
src/modules/presence/presence.c

@@ -136,6 +136,9 @@ static int fixup_refresh_watchers(void** param, int param_no);
 static int fixup_update_watchers(void** param, int param_no);
 static int presence_init_rpc(void);
 
+static int w_pres_has_subscribers(struct sip_msg* _msg, char* _sp1, char* _sp2);
+static int fixup_has_subscribers(void** param, int param_no);
+
 int counter =0;
 int pid = 0;
 char prefix='a';
@@ -187,7 +190,9 @@ static cmd_export_t cmds[]=
 		fixup_refresh_watchers, 0, ANY_ROUTE},
 	{"pres_update_watchers",  (cmd_function)w_pres_update_watchers,  2,
 		fixup_update_watchers, 0, ANY_ROUTE},
-	{"bind_presence",         (cmd_function)bind_presence,           1,
+        {"pres_has_subscribers",  (cmd_function)w_pres_has_subscribers,  2,
+                fixup_has_subscribers, 0, ANY_ROUTE},
+ 	{"bind_presence",         (cmd_function)bind_presence,           1,
 		0, 0, 0},
 	{ 0, 0, 0, 0, 0, 0}
 };
@@ -1829,3 +1834,40 @@ static int sip_uri_case_insensitive_match(str* s1, str* s2)
 	}
 	return strncasecmp(s1->s, s2->s, s2->len);
 }
+
+static int fixup_has_subscribers(void** param, int param_no)
+{
+        if(param_no==1) {
+                return fixup_spve_null(param, 1);
+        } else if(param_no==2) {
+                return fixup_spve_null(param, 1);
+        }
+
+        return 0;
+}
+
+static int w_pres_has_subscribers(struct sip_msg* msg, char* _pres_uri, char* _event)
+{
+        str presentity_uri, watched_event;
+        pres_ev_t* ev;
+
+        if(fixup_get_svalue(msg, (gparam_p)_pres_uri, &presentity_uri)!=0)
+        {
+                LM_ERR("invalid presentity_uri parameter");
+                return -1;
+        }
+
+        if(fixup_get_svalue(msg, (gparam_p)_event, &watched_event)!=0)
+        {
+                LM_ERR("invalid watched_event parameter");
+                return -1;
+        }
+
+	ev = contains_event(&watched_event, NULL);
+	if (ev == NULL) {
+		LM_ERR("event is not registered\n");
+		return -1;
+	}
+
+	return get_subscribers_count(msg, presentity_uri, watched_event) > 0 ? 1 : -1;
+}

+ 70 - 2
src/modules/presence/subscribe.c

@@ -2776,8 +2776,7 @@ int get_db_subs_auth(subs_t* subs, int* found)
 		return -1;
 	}
 
-	if(pa_dbf.query(pa_db, db_keys, 0, db_vals, result_cols,
-				n_query_cols, 2, 0, &result )< 0)
+	if(pa_dbf.query(pa_db, db_keys, 0, db_vals, result_cols, n_query_cols, 2, 0, &result )< 0)
 	{
 		LM_ERR("while querying watchers table\n");
 		if(result)
@@ -2912,3 +2911,72 @@ int insert_db_subs_auth(subs_t* subs)
 error:
 	return -1;
 }
+
+int get_subscribers_count_from_mem(struct sip_msg* msg, str pres_uri, str event)
+{
+	subs_t* s;
+	unsigned int hash_code;
+	int found = 0;
+
+	hash_code = core_case_hash(&pres_uri, &event, shtable_size);
+	lock_get(&subs_htable[hash_code].lock);
+	s= subs_htable[hash_code].entries->next;
+	while(s)
+	{
+		if(s->pres_uri.len==pres_uri.len && strncmp(s->pres_uri.s, pres_uri.s, pres_uri.len)==0)
+			found++;
+		s= s->next;
+	}
+	lock_release(&subs_htable[hash_code].lock);
+	return found;
+}
+
+int get_subscribers_count_from_db(struct sip_msg* msg, str pres_uri, str event)
+{
+ 	db_key_t query_cols[2];
+	db_val_t query_vals[2];
+	db_key_t result_cols[1];
+	db1_res_t *result= NULL;
+	int n_query_cols = 0;
+	int n_result_cols = 0;
+	int found = 0;
+
+	query_cols[n_query_cols] = &str_presentity_uri_col;
+	query_vals[n_query_cols].type = DB1_STR;
+	query_vals[n_query_cols].nul = 0;
+	query_vals[n_query_cols].val.str_val = pres_uri;
+	n_query_cols++;
+
+	query_cols[n_query_cols] = &str_event_col;
+	query_vals[n_query_cols].type = DB1_STR;
+	query_vals[n_query_cols].nul = 0;
+	query_vals[n_query_cols].val.str_val = event;
+	n_query_cols++;
+
+	result_cols[n_result_cols++] = &str_callid_col;
+
+	if (pa_dbf.use_table(pa_db, &active_watchers_table) < 0)
+	{
+		LM_ERR("unsuccessful use_table sql operation\n");
+		return 0;
+	}
+
+	if (!pa_dbf.query(pa_db, query_cols, 0, query_vals,result_cols, n_query_cols, n_result_cols, 0,  &result))
+	{
+		if(result != NULL)
+			found = result->n;
+	}
+
+	pa_dbf.free_result(pa_db, result);
+
+	return found;
+}
+
+int get_subscribers_count(struct sip_msg* msg, str pres_uri, str event)
+{
+	if(subs_dbmode == DB_ONLY) {
+		return get_subscribers_count_from_db(msg, pres_uri, event);
+	} else {
+		return get_subscribers_count_from_mem(msg, pres_uri, event);
+	}
+}

+ 1 - 0
src/modules/presence/subscribe.h

@@ -121,5 +121,6 @@ typedef int (*extract_sdialog_info_t)(subs_t* subs, struct sip_msg* msg,
 		int max_expire, int* to_tag_gen, str scontact, str watcher_user,
 		str watcher_domain);
 void delete_subs(str* pres_uri, str* ev_name, str* to_tag, str* from_tag, str* callid);
+int get_subscribers_count(struct sip_msg* msg, str pres_uri, str event);
 
 #endif