<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
	"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
	[ <!ENTITY % local.common.attrib
	 "xmlns:xi CDATA #FIXED 'http://www.w3.org/2001/XInclude'">]
>

<section id="rpc.main" xmlns:xi="http://www.w3.org/2001/XInclude">
    <!--
    <sectioninfo>
        <releaseinfo role="cvs">$Revision$</releaseinfo>
        <pubdate role="cvs">$Date$</pubdate>
    </sectioninfo>
    -->
 
    <title>
	RPC Control Interface
    </title>

	<section id="rpc.overview">
	<title>Overview of Operation</title>
	<para>
		The RPC (Remote Procedure Call) interface is an interface for
		communicating with external applications. Using it an external
		application can call a function or procedure that will be executed
		inside SIP Server (SER or Kamailio). Function parameters are
		supported as well as returning multiple values as results.
	</para>
	<para>
		By itself RPC consists of two APIs, one for defining RPC functions
		in a transport independent way (called the rpc module api) and one
		for implementing RPC transports.
	</para>
	<para>
		The RPC transports are implemented by writting a RPC
		transport module. The most used transport modules are
		<ulink url='http://www.kamailio.org/docs/modules/devel/modules/ctl/ctl.html'>
		<emphasis>ctl</emphasis>
		</ulink>,
		<ulink url='http://www.kamailio.org/docs/modules/devel/modules/xmlrpc/xmlrpc.html'>
		<emphasis>xmlrpc</emphasis>
		</ulink>
		and
		<ulink url='http://www.kamailio.org/docs/modules/devel/modules/jsonrpc-s/jsonrpc-s.html'>
		<emphasis>jsonrpc-s</emphasis>
		</ulink>.
	</para>
	<para>
		ctl implements a proprietary fast and space efficient
		 RPC encoding over different protocols (unix sockets, UDP, TCP, fifo).
	</para>
	<para>
		xmlrpc uses the de-facto XML-RPC standard encoding
		 (over HTTP TCP or TLS).
	</para>
	<para>
		jsonrpc-s uses the de-facto JSON-RPC standard encoding
		 (over HTTP TCP or TLS).
	</para>
	<para>
		 For more information about the existing transport modules, please 
		 refer to their documentation.
	</para>
	<para>
		When writing a RPC procedure or function, one needs only use the
		RPC API and it will work automatically with all the transports and
		encodings. One needs only to load the desired RPC transport module
		(e.g. xmlrpc).
	</para>
	<para>
		The RPC interface (or API) was created in such a way that would allow
		supporting XML-RPC (because XML-RPC is a de-facto standard), while in
		the same time being very easy to use.
	</para>
	</section>

    <section id="rpc.module_api">
	<title>Module API</title>
	<para>
	    Each module can export RPC functions just like it can export
	    parameters and functions to be called from the script. Whenever SIP server
	    receives an RPC request, it will search through the list of
	    exported RPC functions and the function with matching name will be
	    executed. A couple of essential RPC functions are also embedded into
	    the SIP server core.
	</para>
	<para>
	    This section gives a detailed overview of the whole RPC API. <xref
	    linkend="rpc.rpc_functions"/> describes the prototype and
	    conventions used in RPC functions. <xref linkend="rpc.data_types"/>
	    gives a detailed overview of available data types that can be used
	    in function parameters and return value. <xref
	    linkend="rpc.getting_parameters"/> describes functions of the RPC
	    API that can be used to retrieve parameters of the function, and
	    finally <xref linkend="rpc.creating_result"/> describes functions of
	    the API that can be used to build the result value that will be
	    sent in the reply to the caller.
	</para>
	<para>
	    The whole RPC API is described in header file
	    <filename>sip_router/rpc.h</filename>.  This file defines the set
	    of functions that must be implemented by RPC transport modules, as
	    described in <xref linkend="rpc.new_transport"/>, prototypes of RPC
	    functions and structures used for the communication between RPC
	    transport modules and ordinary modules exporting RPC functions.
	</para>
	<section id="rpc.rpc_functions">
	    <title>RPC Functions</title>
	    <para>
		RPC functions are standard C functions with the following
		prototype:
		<programlisting>
typedef void (*rpc_function_t)(rpc_t* rpc, void* ctx);
		</programlisting>
		RPC functions take two parameters, first parameter is a pointer
		to rpc_t structure and the context. The rpc_t structure
		contains references to all API functions available to the RPC
		function as well as all data necessary to create the
		response. RPC functions do not return any value, instead the
		return value is created using functions from the context. The
		motivation for this decision is the fact that RPC functions
		should always return a response and even the API functions
		called from RPC functions should have the possibility to
		indicate an error (and should not rely on RPC functions doing so).
	    </para>
	    <para>
		If no reply is sent explicitely, the RPC transport module will
		automatically send a "success" reply (e.g. 200 OK for XML-RPC)
		when the RPC function finishes.
		If no values are added to the response, the reponse will be an
		empty "success" reply (e.g. a 200 OK with empty body for
		XML-RPC).
		RPC API functions will automatically send an error reply upon a
		failure.
	    </para>
	    <para>
		Each RPC function has associated an array of documentation
		strings. The purpose of the documentation strings is to give a
		short overview of the function, accepted parameters, and format
		of the reply. By convention the name of the documentation string
		array is same as the name of the function with "_doc" suffix.
	    </para>
	    <para>
		Each module containing RPC functions has to export all the
		RPC functions to SIP server core in order to make them visible to the RPC
		transport modules.
		The export process involves a <emphasis>rpc_export_t</emphasis> 
		structure (either by itself or in an array):
		<programlisting>
<emphasis>
typedef struct rpc_export {
    const char* name;        /* Name of the RPC function (null terminated) */
    rpc_function_t function; /* Pointer to the function */
    const char** doc_str;    /* Documentation strings, method signature and description */
    unsigned int flags;      /* Various flags, reserved for future use */
} rpc_export_t;
</emphasis>
		</programlisting>
		</para>
		<para>
		The <varname>flags</varname> attribute of the
		<varname>rpc_export</varname> structure is reserved for future
		use and is currently unused.
	    </para>
		<para>
		There are several ways of exporting the RPC functions to the SIP server core:
		<itemizedlist>
			<listitem><para>
				register a null terminated array of rpc_export_t structures
				using the <function>rpc_register_array()</function> function
				(defined in rpc_lookup.h), from the module init function
				(mod_init()). This is the <emphasis>recommended</emphasis>
				method for all the new modules.
				<example><title>usrloc RPC Exports Declaration</title>
					<para>
					The <varname>rpc_export_t</varname> array for the modules_s/usrloc
					module looks like:
					</para>
					<programlisting>
<emphasis>
rpc_export_t ul_rpc[] = {
    {"usrloc.statistics",      rpc_stats,           rpc_stats_doc,          0},
    {"usrloc.delete_aor",      rpc_delete_aor,      rpc_delete_aor_doc,     0},
    {"usrloc.delete_contact",  rpc_delete_contact,  rpc_delete_contact_doc, 0},
    {"usrloc.dump",            rpc_dump,            rpc_dump_doc,           0},
    {"usrloc.flush",           rpc_flush,           rpc_flush_doc,          0},
    {"usrloc.add_contact",     rpc_add_contact,     rpc_add_contact_doc,    0},
    {"usrloc.show_contacts",   rpc_show_contacts,   rpc_show_contacts_doc,  0},
    {0, 0, 0, 0}
};
</emphasis>
					</programlisting>
					<para>
					To register it from the module init function one would use
					something similar to:
					</para>
					<programlisting>
	if (rpc_register_array(ul_rpc) != 0) {
		ERR("failed to register RPC commands\n");
		return -1;
	}
					</programlisting>
				</example>
			</para></listitem>
			<listitem><para>
				register RPCs one by one using the
				<function>rpc_register_function()</function>
				(defined in rpc_lookup.h), from the module init function.
			</para></listitem>
			<listitem><para>
				register a null terminated array of rpc_export_t structures
				using the SIP server module interface SER_MOD_INTERFACE (specific
				for SER flavour).
				For this purpose, the
				<varname>module_exports</varname> structure of SIP server module API
				contains a new attribute called <varname>rpc_methods</varname>:
				<programlisting>
struct module_exports {
    char* name;                 /* null terminated module name */	
    cmd_export_t* cmds;         /* null terminated array of the exported commands */
    <emphasis>rpc_export_t* rpc_methods;</emphasis>  /* null terminated array of exported rpc methods */
    param_export_t* params;     /* null terminated array of the exported module parameters */
    
    init_function init_f;         /* Initialization function */
    response_function response_f; /* function used for responses */
    destroy_function destroy_f;   /* function called upon shutdown */
    onbreak_function onbreak_f;
    child_init_function init_child_f;  /* function called by all processes after the fork */
};
				</programlisting>
				<varname>rpc_methods</varname> is a pointer to an array of
				rpc_export_t structures. The last element of the array is a
				bumper containing zeroes in all the attributes of the
				structure. The following program listing shows the exported RPC
				functions of the modules_s/usrloc module, using the rpc_export_t array
				<emphasis>ul_rpc</emphasis> defined above, in the 
				rpc_register_array() example:
				<example><title>usrloc Module Exports Declaration</title>
					<programlisting>
struct module_exports exports = {
    "usrloc",
    cmds,      /* Exported functions */ 
    <emphasis>ul_rpc</emphasis>,    /* RPC methods */
    params,    /* Export parameters */ 
    mod_init,  /* Module initialization function */ 
    0,         /* Response function */ 
    destroy,   /* Destroy function */ 
    0,         /* OnCancel function */ 
    child_init /* Child initialization function */ };

					</programlisting>
				</example>
				<note><para>
					This mode works only with modules using the SER flavour module
					interface. It does not work for kamailio modules and it
					will probably not work for future sip-router modules. It is
					safer and recommended to use instead the
					<function>rpc_register_array()</function> function.
				</para></note>
			</para></listitem>
		</itemizedlist>
		</para>
		<para>
			By convention the name of every exported function consists of
			two parts delimited by a dot. The first part is the name of the
			module or SIP server subsystem this function belongs to. The second
			part is the name of the function.
		</para>
	</section>

	<section id="rpc.data_types">
	    <title>Data Types</title>
	    <para>
		The RPC API defines several basic and 1 compound data type
		that can be used in communication with the caller of RPC
		functions. The RPC API uses formating strings to describe data
		types. Each data type is described by exactly one character in
		the formating string. For example, if an RPC function calls
		function <function>add</function> of the RPC API and it passes
		two parameters to it, the first one of type string and the
		second one of type integer, the function parameters will look
		like:
		<programlisting>
add("sd", string_param, int_param);
		</programlisting>
		Character "s" in the formating string tells to the function
		that the 2nd parameter should be interpreted as string,
		character "d" in the formating string tells to the function
		that the 3rd parameter should be interpreted as signed integer.
	    </para>
	    <formalpara>
		<title>Integer</title>
		<para>
		    Integer type represents a signed 32-bit
		    integer. Corresponding character in the formating string is
		    "d". This parameter can be stored in C-style variable with
		    type <varname>int</varname>.
		</para>
	    </formalpara>
	    <formalpara>
		<title>Float</title>
		<para>
		    Float type represents a signed floating point
		    number. Corresponding character in the formating string is
		    "f". Data of this type can be stored in C-style variables
		    of type <varname>double</varname>.
		</para>
	    </formalpara>
	    <formalpara>
		<title>String</title>
		<para>
		    String type represents a string of characters. The string
		    may contain zeroes. This data type is represented by two
		    characters in the formatting string, either "s" or "S". "s"
		    indicates to the conversion function that the result should
		    be stored in a variable of type <varname>char*</varname>
		    and it should be zero terminated. "S" indicates to the
		    conversion function that the result will be stored in
		    a variable of type <varname>str</varname> which contains
		    both the pointer to the beginning of the string and its
		    length.
		</para>
	    </formalpara>
	    <formalpara>
		<title>Structure</title>
		<para>
		    Structure is the only compound data type currently defined
		    in the API. A structure is a collection of attributes. Each
		    attribute is identified using name (string) and each
		    attribute can be one of the basic data types, that
		    is integer, float, or string. Nesting of structures is not
		    allowed (in other words, structure attributes cannot be of
		    type struct again). Corresponding character in the
		    formatting string is "{".
		</para>
	    </formalpara>
		<formalpara>
		<title>Optional parameters</title>
		<para>
			Optional parameters can be used, but only in the
			<function>scan</function> function.  For optional parameters the
			<function>scan</function> function will not automatically generate
			a rpc fault if the input ends. Note that in this case the
			<function>scan</function> will still return a negative value
			(minus the number of parameters successfully read).
			Optional parameters can be marked in the format string by
			preceding the first optional parameter type with a "*".
			All the parameters following a "*" are considered to be optional.
			For example for the format string "ds*dds", the last 3 parameters
			(2 ints and a string) are optional.
		</para>
		</formalpara>
	    <table>
		<title>Data Type Overview</title>
		<tgroup cols="3">
		    <tbody>
			<row rowsep="1">
			    <entry>Name</entry>
			    <entry>Formating String Char</entry>
			    <entry>C-Style Variable</entry>
			</row>
			<row>
			    <entry>Integer</entry>
			    <entry>d</entry>
			    <entry>int</entry>
			</row>
			<row>
			    <entry>Float</entry>
			    <entry>f</entry>
			    <entry>double</entry>
			</row>
			<row>
			    <entry>String</entry>
			    <entry>s</entry>
			    <entry>char*</entry>
			</row>
			<row>
			    <entry>String</entry>
			    <entry>S</entry>
			    <entry>str*</entry>
			</row>
			<row>
				<entry>Optional modifier</entry>
				<entry>*</entry>
				<entry>marks all further parameters as optional</entry>
			</row>
			<row>
				<entry>Autoconvert modifier</entry>
				<entry>.</entry>
				<entry>requires auto-conversion for the next parameter</entry>
			</row>
		    </tbody>
		</tgroup>
	    </table>
	</section>

	<section id="rpc.getting_parameters">
	    <title>Getting Parameters</title>
	    <para>
		Each RPC function call can contain parameters. Parameters have
		no name, their meaning is determined by their position in the
		parameter set.
		<note>
		    <para>
			You can pass all parameters to a function within a
			structure if you want to make them position
			independent. Then each parameter can be retrieved by
			its name regardless of its position.
		    </para>
		</note>
		There are two functions in the RPC API that can be used to
		obtain function call parameters: <function>scan</function> and
		<function>struct_scan</function>.
	    </para>
	    <section id="rpc.scan">
		<title><function>scan</function></title>
		<para>
		    Function <function>scan</function> can be used to retrieve
		    parameters from the parameter set. The function accepts
		    variable number of parameters. The first parameter is the
		    formatting string that determines the type of the
		    parameters to be retrieved. Each parameter is represented by
		    exactly one parameter type character in the string.
			The variable part of parameters must contain as many pointers to C
			variables as there are formatting non-modifiers characters in the
			formatting string.
		    <warning>
			<para>
			    The function will crash if you fail to provide
			    enough parameters.
			</para>
		    </warning>
		</para>
		<para>
			Besides characters representing parameter types, the formatting
			string can contain two special modifiers: "*" and ".". The
			modifiers do not have a correspondent in the variable part of the
			parameters.
		</para>
		<para>
			The meaning of "*" modifier is that any further parameters
			(defined by other type characters in the formatting string) are
			optional (they can be missing in the input and no rpc fault will
			automatically be generated).
		</para>
		<para>
			The '.' modifiers turns on type autoconversion for the next
			parameter. This means that if the type of the next parameter 
			differs from the type specified in the formatting string, the
			parameter will be automatically converted to the formatting string
			type (if possible) and if the automatic conversion succeeds, no
			fault will be generated.
		</para>
		<para>
			The function returns the number of parameters read on success
			(a number greater or equal 0) and - (minus) the number of
			parameters read on error (for example for an error after 
			reading 2 parameters it will return -2).
			When a failure occurs (incorrect parameter type or no more
			parameters in the parameter set) the function will
			return a negative number (- number of parameters read so far)
			and it will also automatically change the reply that will be
			sent to the caller to indicate that a failure has occurred on 
			the server (unless the "*" is used and the error is lack
			of more parameters).
		</para>
		<para>
			The prototype of the function is:
		    <programlisting>
int scan((void* ctx, char* fmt, ...)
		    </programlisting>
		    It is possible to either call the function once to scan all
		    the parameters:
		    <programlisting>
rpc->scan(ctx, "sdf", &amp;string_val, &amp;int_val, &amp;double_val);
		    </programlisting>
		    Or you can call the same function several times and it will
		    continue where it left off previously:
		    <programlisting>
rpc->scan(ctx, "s", &amp;string_val);
rpc->scan(ctx, "d", &amp;int_val);
rpc->scan(ctx, "f", &amp;double_val);
		    </programlisting>
		</para>
		<para>
		</para>
	    </section>
	    <section>
		<title><function>struct_scan</function></title>
		<para>
			Function <function>struct_scan</function> can be used to
			retrieve named attributes from a parameter of type
			structure.
			<note><para>
			This function is obsolete and not implemented by all the
			rpc transports (e.g.: ctl / binrpc). Consider using the normal
			<function>scan</function> instead.
			</para></note>
			When retrieving a structure parameter from the
			parameter set:
		    <programlisting>
rpc->scan(ctx, "{", &amp;handle);
		    </programlisting>
		    The corresponding variable (named 
		    <varname>handle</varname> in the example above) will contain
		    the index of the structure parameter within the parameter
		    set, but the index cannot be used to retrieve the contents
		    of the structure. To retrieve the contents of the structure
		    you can use function <function>struct_scan</function>. The
		    function gets the handle as the first parameter:
		    <programlisting>
rpc->struct_scan(handle, "sd", "str_attr", &amp;str_val, "int_attr", &amp;int_val);
		    </programlisting>
		    The second parameter is the formatting string followed by
		    pairs of parameters. First parameter in each pair is the
		    name of the attribute to retrieve (string) and the second
		    parameter in each pair is the pointer to the variable to
		    store the value of the parameter. The function returns the
			number of parameters (name value pairs) read on
		    success and - number of parameters read so far on an error
			(just like the <function>scan</function> function). The function
			also indicates an error if a requested attribute is missing in
		    the structure.
		</para>
	    </section>
	
		<section><title>Retrieving Parameters Example</title>
		<example>
		<title>Retrieving Parameters</title>
		<programlisting>
<![CDATA[
static void rpc_delete_contact(rpc_t* rpc, void* ctx)
{
    str aor, contact;
    char* table;
    void *handle;
    int   expires;
    double q;

    if (rpc->scan(ctx, "sS{", &table, &aor, &handle) < 0) {
        /* Reply is set automatically by scan upon failure,
         * no need to do anything here
         */
        return;
    }

    if (rpc->struct_scan(handle, "Sdf", "Contact", &contact,
                                        "Expires", &expires,
                                        "Q",       &q        ) < 0) {
        /* Reply is set automatically by struct_scan upon failure,
         * no need to do anything here
         */
        return;
    }

    /* Process retrieved parameters here */
}

/* variable number of parameters:
   echo back all the parameters, string type required */
static void core_prints(rpc_t* rpc, void* c)
{
	char* string = 0;
	while((rpc->scan(c, "*s", &string)>0))
		rpc->add(c, "s", string);
}

/* variable number of parameters and auto conversion:
   echo back all the parameters, works with any type (everything is 
   internally converted to string, notice the '.' modifier) */
static void core_echo(rpc_t* rpc, void* c)
{
	char* string = 0;
	while((rpc->scan(c, "*.s", &string)>0))
		rpc->add(c, "s", string);
}

]]>
		</programlisting>
	    </example>
		</section>
	</section>

	<section id="rpc.creating_result">
	    <title>Building Reply</title>
	    <para>
		The RPC API contains several functions that can be used to
		modify and/or send a reply. The functions use formatting
		strings and parameter lists just like functions described in
		<xref linkend="rpc.getting_parameters"/>.
	    </para>
	    <para>
		Each RPC function call must return a reply. The reply can be
		either a failure reply or success reply. Failure replies
		contain only the status code and reason phrase. Success
		replies can have arbitrary amount of data attached to
		them. Status codes 3xx, 4xx, 5xx, and 6xx indicate
		failures. Status code 2xx indicates success.
	    </para>
	    <para>
		The default reply is 200 OK with no data attached to it. This
		is what will be returned by the RPC transport module if you do
		not call any of the reply-related functions described in this
		section.
		<example>
		    <title>Sending default reply</title>
		    <programlisting>
<![CDATA[
static void rpc_dummy(rpc_t* rpc, void *ctx)
{
  /* 200 OK with no data will be returned */
}
]]>
		    </programlisting>
		</example>
	    </para>
	    <section>
		<title>fault</title>
		<para>
		    You can use <function>fault</function> function to indicate
		    that an error has occurred on the server to the caller. The
		    function accepts two parameters. The first parameter is the
		    status code and the second parameter is the reason phrase.
		    <programlisting>
<![CDATA[
static void rpc_my_function(rpc_t* rpc, void *ctx)
{
    rpc->fault(ctx, 600, "Not Yet Implemented");
}
]]>
		    </programlisting>
		    If your function first creates some result using
		    <function>add</function>, or <function>printf</function>
		    functions then all the data will be lost once you call
		    <function>fault</function> function. Failure replies must
		    not contain any data:
		    <programlisting>
<![CDATA[
static void rpc_my_function(rpc_t* rpc, void *ctx)
{
    rpc->add(ctx, "s", "result1");
    rpc->add(ctx, "d", variable);

    /* Reply created by previous functions will be
     * deleted and a failure reply 600 Not Yet Implemented
     * will be created instead
     */
    rpc->fault(ctx, 600, "Not Yet Implemented");

    /* You can also add data here, but that will have no
     * effect
     */
    rpc->add(ctx, "s", "result2");
}
]]>
		    </programlisting>
		    Similarly you can also call <function>add</function> or
		    <function>printf</function> functions after calling
		    <function>fault</function>, in this case they will have no
		    effect:
		    <programlisting>
<![CDATA[
static void rpc_my_function(rpc_t* rpc, void *ctx)
{
    rpc->fault(ctx, 600, "Not Yet Implemented");

    /* You can also add data here, but that will have no
     * effect and only 600 Not Yet Implemented will be returned
     */
    rpc->add(ctx, "s", "result2");
}
]]>
		    </programlisting>
		</para>
	    </section>
	    <section>
		<title>send</title>
		<para>
		    RPC functions can use function <function>send</function> to
		    explicitly send the reply. Each RPC function call generates
		    exactly one reply. No reply will be sent after the function
		    finishes if it already sent the reply using
		    <function>send</function> function explicitly. This
		    function is especially useful if the RPC function needs to
		    perform some (potentially destructive) actions after the
		    reply has been sent.
		</para>
		<example>
		    <title>Kill the server</title>
		    <programlisting>
<![CDATA[
static void core_kill(rpc_t* rpc, void *ctx)
{
    int sig_no;

    if (rpc->scan(ctx, "d", &sig_no) < 0) return;
    rpc->send(ctx, );     /* First send a reply */
    kill(0, sig_no); /* Then kill the server */
}
]]>
		    </programlisting>
		</example>
		
	    </section>
	    <section>
		<title>add</title>
		<para>
		    Function <function>add</function> can be used to add
		    arbitrary data to the result set. Its parameters and use
		    are analogical to <function>scan</function> function
		    described in <xref linkend="rpc.scan"/>. The first
		    parameter of the function is the formatting string that
		    determines the types of additional parameters:
		    <programlisting>
<![CDATA[
static void rpc_func(rpc_t* rpc, void *ctx)
{
    str str_result;
    int int_result;
    void *handle;
    double float_result;

    if (rpc->add(ctx, "Sdf{", &str_result, int_result, float_result, &handle) < 0) return;
}
]]>
		    </programlisting>
		    Naturally you can call this function several times, adding
		    only one piece of data at a time. The function returns 0 on
		    success and -1 on an error. In case of an error the reply
		    is set automatically with corresponding error code and
		    reason phrase.
		</para>
		<para>
		    The last character in the formatting string of the function
		    above indicates that the last data to be added will be a
		    structure. This deserves some clarification. In this case,
		    the function will create an empty structure and the handle
		    to the newly created structure will be stored in
		    <varname>handle</varname> variable (hence the last
		    parameter is pointer to an integer). In this particular
		    example parameters <varname>str_result</varname>,
		    <varname>int_result</varname>, and
		    <varname>float_result</varname> will be used for reading
		    while parameter <varname>handle</varname> will be used for
		    writing by the function.
		</para>
		<para>
		    You can set the attributes of the newly created structure
		    using <function>struct_add</function> function described in
		    <xref linkend="rpc.struct_add"/>.
		</para>
	    </section>
	    <section>
		<title>rpl_printf</title>
		<para>
		    <varname>rpl_printf</varname> is a convenience function. The
		    function adds data of type string to the result set. The
		    first parameter of the function is again a formatting
			string, but this time it is standard
			<function>printf</function>-like formatting string:
		    <programlisting>
<![CDATA[
if (rpc->rpl_printf(ctx, "Unable to delete %d entries from table %s", num_entries, table_name) < 0) return;
]]>
		    </programlisting>
		    The return value of the function is the same as of
		    <function>add</function> function.
		</para>
	    </section>
	    <section id="rpc.struct_add">
		<title>struct_add</title>
		<para>
		    Function <function>struct_add</function> can be used to add
		    attributes to a structure (created previously by
		    <function>add</function> function). The first parameter of
		    the function is handle obtained through
		    <function>add</function> function, the second parameters is
		    formatting string that determines the types of attributes
		    to be added. There must be two parameters per each
		    character in the formatting string, the first one is the
		    name of the attribute, the second parameter is the value
		    of the attribute. If a parameter with such a name already
		    exist in the structure then it will be overwritten with the
		    new value.
		    <programlisting>
<![CDATA[
static void rpc_func(rpc_t* rpc, void *ctx)
{
    void *handle;

        /* Create empty structure and obtain its handle */
    if (rpc->add(ctx, "{", &handle) < 0) return;
        /* Fill-in the structure */
    if (rpc->struct_add(handle, "sd", "attr1", str_val,
                                      "attr2", int_val ) < 0)
        return;
}
]]>
		    </programlisting>
		    The function returns -1 on an error (and sets the status
		    code and reason phrase of the reply accordingly) and 0 on success.
		</para>
	    </section>
	</section>

	<section>
	    <title>Real World Example</title>
	    <para>
		The following example illustrates the use of most of the
		functions from the API together:
	    </para>
	    <example>
		<title>Real World Example RPC Function</title>
		<programlisting>
<![CDATA[
static void rpc_register(rpc_t* rpc, void *ctx)
{
    char* domain;
    str aor;
    contact_t contact, new_contact;
    void *handle;

        /* Extract the domain, address of record from the request */
    if (rpc->scan(ctx, "sS{", &domain, &aor, &handle) < 0) return;
        /* Extract the structure describing the contact to be processed */
    if (rpc->struct_scan(handle, "Sdf", "Contact", &contact.c,
                                        "Expires", &contact.expires,
                                        "Q",       &contact.q       ) < 0)
        return;

        /* Process the contact, new_contact will contain updated value after processing */
    if (process_contact(domain, &aor, &new_contact, &contact) < 0) {
           /* Processing failed, indicate the failure to the caller */
        rpc->fault(ctx, 500, "Error While Processing Contact");
        return;
    }

        /* Return the domain and the address of record */
    rpc->add(ctx, "sS{", &domain, &aor, &handle) < 0) return;
        /* And also add the new values for contact, q, and expires parameters */
    rpc->struct_add(handle, "Sdf", "Contact", &new_contact.c,
                                   "Expires", &new_contact.expires,
                                   "Q",       &new_contact.q       );
}
]]>
		</programlisting>
	    </example>
	</section>
    </section>

	<section id="rpc.client_examples">
	<title>Client Examples</title>
	<para>
	<itemizedlist>
		<listitem><para>
		<emphasis>sercmd</emphasis> (C application that uses the
		<emphasis>binrpc</emphasis> interface implemented by the
		<emphasis>ctl</emphasis> module).
		</para></listitem>
		<listitem><para>
		<emphasis>ser_ctl</emphasis> (python application that uses the
		<emphasis>XML-RPC</emphasis> interface implemented by the
		<emphasis>xmlrpc</emphasis>
		module).
		</para></listitem>
		<listitem><para>
		<emphasis>serweb</emphasis> (php application that can use
		the <emphasis>XML-RPC</emphasis> interface to call ser 
		functions).
		</para></listitem>
	</itemizedlist>
	</para>
	</section>

    <section id="rpc.new_transport">
	<title>Implementing New Transports</title>
	<remark>
	To be done.
	</remark>
	<!-- TODO:
	- create a new module
	- take a look at sip_router/rpc.h
	- implement all functions in that header field
	- no garbage collection in rpc functions, the module needs to keep
	track of all allocated data
	- return value default to true
	- parameter type conflict is an error
	- missing struct attribute is an error
	- always send a reply, prepare replies so that you do not have to
	allocate memory at runtime
	- str strings do not have to be zero terminated
	- no structure/array nesting allowed
	- printf creates string attribute
        -->
	<para>
		Examples:
		<itemizedlist>
			<listitem><para>
				<emphasis>ctl</emphasis>
			</para></listitem>
			<listitem><para>
				<emphasis>xmlrpc</emphasis>
			</para></listitem>
		</itemizedlist>
	</para>
    </section>

<section id="rpc.xmlrpc_examples">
	<title>Examples using xmlrpc</title>
	<para>See the <varname>xmlrpc</varname> module documentation:
	<ulink url='http://sip-router.org/docbook/sip-router/branch/master/modules/xmlrpc/xmlrpc.html'>modules/xmlrpc/README</ulink>.
	</para>
</section>

</section>