[sr-dev] git:master: pv Add RPC commands shvGet and shvSet to manipulate and list shared variables

Olle E. Johansson oej at edvina.net
Sat Mar 2 15:53:54 CET 2013


Module: sip-router
Branch: master
Commit: ab1d5bf573b43daf204eb1572083c8f12791a3e1
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ab1d5bf573b43daf204eb1572083c8f12791a3e1

Author: Olle E. Johansson <oej at edvina.net>
Committer: Olle E. Johansson <oej at edvina.net>
Date:   Sat Mar  2 15:53:08 2013 +0100

pv Add RPC commands shvGet and shvSet to manipulate and list shared variables

---

 modules/pv/README           |   41 +++++++++++-
 modules/pv/doc/pv_admin.xml |   34 ++++++++++
 modules/pv/pv.c             |   35 ++++++++++
 modules/pv/pv_shv.c         |  147 +++++++++++++++++++++++++++++++++++++++++++
 modules/pv/pv_shv.h         |    3 +
 5 files changed, 257 insertions(+), 3 deletions(-)

diff --git a/modules/pv/README b/modules/pv/README
index 162b7f0..7c5f40e 100644
--- a/modules/pv/README
+++ b/modules/pv/README
@@ -45,6 +45,11 @@ Daniel-Constantin Mierla
               5.1. shv_set
               5.2. shv_get
 
+        6. RPC Commands
+
+              6.1. pv.shvSet
+              6.2. pv.shvGet
+
    List of Examples
 
    1.1. shvset parameter usage
@@ -87,6 +92,11 @@ Chapter 1. Admin Guide
         5.1. shv_set
         5.2. shv_get
 
+   6. RPC Commands
+
+        6.1. pv.shvSet
+        6.2. pv.shvGet
+
 1. Overview
 
    This module collects the core pseudo-variables that can be used in
@@ -207,7 +217,7 @@ if(pv_isset("$avp("s:x")"))
 pv_unset("$avp("s:x")");
 ...
 
-4.3. is_int(pvar)
+4.3.  is_int(pvar)
 
    Function checks if pvar argument contains integer value and returns 1
    if it does and -1 otherwise.
@@ -221,7 +231,7 @@ if (is_int("$var(foo)")) {
 }
 ...
 
-4.4. typeof(pvar, vtype)
+4.4.  typeof(pvar, vtype)
 
    Returns true if the type of pseudo-variable matches the second
    parameter. The second parameter can be: 'int' - type is integer; 'str'
@@ -236,7 +246,7 @@ if (typeof("$var(foo)", "str")) {
 }
 ...
 
-4.5. not_empty(pvar)
+4.5.  not_empty(pvar)
 
    Returns true if the pseudo-variables has the type string and is not
    empty value.
@@ -296,3 +306,28 @@ $ kamctl fifo shv_set debug int 0
 $ kamctl fifo shv_get debug
 $ kamctl fifo shv_get
 ...
+
+6. RPC Commands
+
+   6.1. pv.shvSet
+   6.2. pv.shvGet
+
+6.1. pv.shvSet
+
+   Set the value of a shared variable ($shv(name)).
+
+   Parameters:
+     * _name_: shared variable name
+     * _type_: type of the value
+          + "int": integer value
+          + "str": string value
+     * _value_: value to be set
+
+6.2. pv.shvGet
+
+   Get the value of a shared variable ($shv(name)).
+
+   Parameters:
+     * _name_: shared variable name
+
+   If no name is given, all shared variables are listed
diff --git a/modules/pv/doc/pv_admin.xml b/modules/pv/doc/pv_admin.xml
index 68bbc9c..884e1ad 100644
--- a/modules/pv/doc/pv_admin.xml
+++ b/modules/pv/doc/pv_admin.xml
@@ -336,5 +336,39 @@ $ &ctltool; fifo shv_get
 			</example>
 		</section>
 	</section>
+	<section>
+        <title>RPC Commands</title>
+		<section>
+			<title><function moreinfo="none">pv.shvSet</function></title>
+			<para>
+				Set the value of a shared variable ($shv(name)).
+			</para>
+		<para>Parameters:</para>
+		<itemizedlist>
+			<listitem><para>_name_: shared variable name</para></listitem>
+			
+			<listitem><para>_type_: type of the value</para>
+			      <itemizedlist>
+	    <listitem><para> <quote>int</quote>: integer value </para></listitem> 
+		<listitem><para> <quote>str</quote>: string value </para></listitem>	
+				  </itemizedlist>
+			</listitem>	  
+
+			<listitem><para>_value_: value to be set</para></listitem>
+		</itemizedlist>
+		</section>
+		<section>
+			<title><function moreinfo="none">pv.shvGet</function></title>
+			<para>
+				Get the value of a shared variable ($shv(name)).
+			</para>
+		<para>Parameters:</para>
+		<itemizedlist>
+			<listitem><para>_name_: shared variable name</para></listitem>
+		</itemizedlist>
+		<para>If no name is given, all shared variables are listed</para>
+		</section>
+	</section>
+	
 </chapter>
 
diff --git a/modules/pv/pv.c b/modules/pv/pv.c
index 0b22faf..d1d4b2b 100644
--- a/modules/pv/pv.c
+++ b/modules/pv/pv.c
@@ -28,6 +28,9 @@
 #include "../../pvar.h"
 #include "../../mod_fix.h"
 #include "../../lib/kmi/mi.h"
+#include "../../rpc.h"
+#include "../../rpc_lookup.h"
+
 
 #include "pv_branch.h"
 #include "pv_core.h"
@@ -448,6 +451,7 @@ static int pv_unset(struct sip_msg* msg, char* pvid, char *foo);
 static int is_int(struct sip_msg* msg, char* pvar, char* s2);
 static int pv_typeof(sip_msg_t *msg, char *pv, char *t);
 static int pv_not_empty(sip_msg_t *msg, char *pv, char *s2);
+static int pv_init_rpc(void);
 
 static cmd_export_t cmds[]={
 	{"pv_isset",  (cmd_function)pv_isset,  1, fixup_pvar_null, 0, 
@@ -495,6 +499,11 @@ static int mod_init(void)
 		LM_ERR("failed to register MI commands\n");
 		return -1;
 	}
+	if(pv_init_rpc()!=0)
+        {
+                LM_ERR("failed to register RPC commands\n");
+                return -1;
+        }
 
 	return 0;
 }
@@ -629,3 +638,29 @@ static int is_int(struct sip_msg* msg, char* pvar, char* s2)
 
 	return -1;
 }
+
+static const char* rpc_shv_set_doc[2] = {
+	"Set a shared variable (args: name type value)",
+	0
+};
+
+static const char* rpc_shv_get_doc[2] = {
+	"Get the value of a shared variable. If no argument, dumps all",
+	0
+};
+
+rpc_export_t pv_rpc[] = {
+	{"pv.shvSet", rpc_shv_set, rpc_shv_set_doc, 0},
+	{"pv.shvGet", rpc_shv_get, rpc_shv_get_doc, 0},
+	{0, 0, 0, 0}
+};
+
+static int pv_init_rpc(void)
+{
+	if (rpc_register_array(pv_rpc)!=0)
+	{
+		LM_ERR("failed to register RPC commands\n");
+		return -1;
+	}
+	return 0;
+}
diff --git a/modules/pv/pv_shv.c b/modules/pv/pv_shv.c
index 548ab04..dc0109f 100644
--- a/modules/pv/pv_shv.c
+++ b/modules/pv/pv_shv.c
@@ -2,6 +2,7 @@
  * $Id$
  *
  * Copyright (C) 2007 Elena-Ramona Modroiu
+ * Copyright (C) 2013 Olle E. Johansson
  *
  * This file is part of Kamailio, a free SIP server.
  *
@@ -615,6 +616,152 @@ error:
 	return NULL;
 }
 
+
+void rpc_shv_get(rpc_t* rpc, void* c)
+{
+	str varname;
+	int allvars = 0;
+	sh_var_t *shv = NULL;
+	void* th;
+        void* ih;
+        void* vh;
+
+	if (rpc->scan(c, "S", &varname) != 1) {
+		allvars = 1;
+        }
+
+	if (!allvars) {
+		/* Get one variable value */
+		shv = get_shvar_by_name(&varname);
+		if(shv==NULL) {
+			rpc->fault(c, 404, "Variable not found");
+			return;
+		}
+		if (rpc->add(c, "{",  &ih) < 0)
+        	{
+               		rpc->fault(c, 500, "Internal error creating rpc");
+                	return;
+        	}
+		
+		lock_shvar(shv);
+		if(shv->v.flags&VAR_VAL_STR)
+		{
+			if(rpc->struct_add(ih, "sss", "name", varname.s, "type", "string", "value", shv->v.value.s.s) < 0)
+			{
+				rpc->fault(c, 500, "Internal error creating rpc data (str)");
+				unlock_shvar(shv);
+				return;
+			}
+		} else {
+			if(rpc->struct_add(ih, "ssd", "name", varname.s, "type", "int", "value", shv->v.value.n) < 0)
+			{
+				rpc->fault(c, 500, "Internal error creating rpc data (int)");
+				unlock_shvar(shv);
+				return;
+			}
+		}
+		unlock_shvar(shv);
+
+		return;
+	}
+	if (rpc->add(c, "{", &th) < 0)
+       	{
+         	rpc->fault(c, 500, "Internal error creating rpc");
+               	return;
+       	}
+
+	if(rpc->struct_add(th, "{", "items", &ih) < 0)
+               {
+                         rpc->fault(c, 500, "Internal error creating rpc th");
+                         return;
+               }
+
+	for(shv=sh_vars; shv; shv=shv->next)
+	{
+		lock_shvar(shv);
+		if(rpc->struct_add(ih, "{", "shv", &vh) < 0)
+               {
+                         rpc->fault(c, 500, "Internal error creating rpc th");
+                         return;
+               }
+		if(shv->v.flags&VAR_VAL_STR)
+		{
+			if(rpc->struct_add(vh, "sss", "name", shv->name.s, "type", "string", "value", shv->v.value.s.s) < 0)
+			{
+				rpc->fault(c, 500, "Internal error creating rpc data");
+				unlock_shvar(shv);
+				return;
+			}
+		} else {
+			if(rpc->struct_add(vh, "ssd", "name", shv->name.s, "type", "int", "value", shv->v.value.n) < 0)
+			{
+				rpc->fault(c, 500, "Internal error creating rpc data");
+				unlock_shvar(shv);
+				return;
+			}
+		}
+		unlock_shvar(shv);
+	}
+
+	return ;
+}
+
+void rpc_shv_set(rpc_t* rpc, void* c)
+{
+	str varname, type, value;
+	int ival = 0;
+	int_str isv;
+	sh_var_t *shv = NULL;
+	int flags = 0;
+	LM_DBG("Entering SHV_set\n");
+
+	if (rpc->scan(c, "S", &varname) != 1) {
+		rpc->fault(c, 500, "Missing parameter varname (Parameters: varname type value)");
+		return;
+        }
+	LM_DBG("SHV_set Varname %.*s \n", varname.len, varname.s);
+	if (rpc->scan(c, "S", &type) != 1) {
+		rpc->fault(c, 500, "Missing parameter type (Parameters: varname type value)");
+		return;
+        }
+	if (strcasecmp(type.s, "int") == 0 ) {
+		if (rpc->scan(c, "d", &ival) != 1) {
+			rpc->fault(c, 500, "Missing integer parameter value (Parameters: varname type value)");
+			return;
+        	}
+		isv.n = ival;
+	} else  if (strcasecmp(type.s, "str") == 0 ) {
+		/* String value */
+		if (rpc->scan(c, "S", &value) != 1) {
+			rpc->fault(c, 500, "Missing parameter value (Parameters: varname type value)");
+			return;
+        	}
+		isv.s = value;
+		flags = VAR_VAL_STR;
+	} else {
+		rpc->fault(c, 500, "Unknown parameter type (Types: int or str)");
+		return;
+	}
+
+	shv = get_shvar_by_name(&varname);
+	if(shv==NULL) {
+		rpc->fault(c, 404, "Variable not found");
+		return;
+	}
+		
+	lock_shvar(shv);
+	if(set_shvar_value(shv, &isv, flags)==NULL)
+	{
+		rpc->fault(c, 500, "Cannot set shared variable value");
+		LM_ERR("cannot set shv value\n");
+	} else {
+		rpc->printf(c, "Ok. Variable set to new value.");
+	}
+
+	unlock_shvar(shv);
+	return;
+}
+
 int param_set_xvar( modparam_t type, void* val, int mode)
 {
 	str s;
diff --git a/modules/pv/pv_shv.h b/modules/pv/pv_shv.h
index d47b0ac..0db4800 100644
--- a/modules/pv/pv_shv.h
+++ b/modules/pv/pv_shv.h
@@ -69,5 +69,8 @@ struct mi_root* mi_shvar_set(struct mi_root* cmd_tree, void* param);
 int param_set_var( modparam_t type, void* val);
 int param_set_shvar( modparam_t type, void* val);
 
+void rpc_shv_get(rpc_t* rpc, void* c);
+void rpc_shv_set(rpc_t* rpc, void* c);
+
 #endif
 




More information about the sr-dev mailing list