Browse code

doc: rpc docs split into rpc api and xmlrpc modules docs

- doc/rpc/ser_rpc.xml split into ser_rpc.xml (that contains now
only generic RPC documentation) and
modules_s/xmlrpc/doc/xmlrpc.xml (that contains xmlrpc specific
stuff).
- slight updates and fixes

Andrei Pelinescu-Onciul authored on 11/05/2009 13:59:54
Showing 5 changed files
... ...
@@ -9,360 +9,54 @@
9 9
         <pubdate role="cvs">$Date$</pubdate>
10 10
     </sectioninfo>
11 11
     -->
12
-    
12
+ 
13 13
     <title>
14 14
 	SER Management Interface
15 15
     </title>
16 16
 
17
-    <section id="rpc.design">
18
-	<title>Design Goals</title>
19
-	<para>
20
-	    
21
-	</para>
22
-	<itemizedlist>
23
-	    <listitem>
24
-		<para>Implemented as a module.</para>
25
-	    </listitem>
26
-	    <listitem>
27
-		<para>API independent of transport protocols.</para>
28
-	    </listitem>
29
-	    <listitem>
30
-		<para>Reuse transports available in SER.</para>
31
-	    </listitem>
32
-	    <listitem>
33
-		<para>The possibility to encrypt all communication.</para>
34
-	    </listitem>
35
-	    <listitem>
36
-		<para>The possibility to authenticate clients.</para>
37
-	    </listitem>
38
-	    <listitem>
39
-		<para>Easy integration with existing languages and
40
-		    implementations.</para>
41
-	    </listitem>
42
-	    <listitem>
43
-		<para>
44
-		    Easy and straightforward implementation of management
45
-		    functions in SER modules.
46
-		</para>
47
-	    </listitem>
48
-	</itemizedlist>
49
-    </section>
50
-
51
-    <section id="rpc.overview">
17
+	<section id="rpc.overview">
52 18
 	<title>Overview of Operation</title>
53 19
 	<para>
54
-	    The RPC (Remote Procedure Call) interface of SER is based on the
55
-	    XML-RPC <ulink url="http://www.xmlrpc.com">de-facto
56
-	    standard</ulink>. XML-RPC protocol encodes the name of the method
57
-	    to be called along with its parameter in an XML document which is
58
-	    then conveyed using HTTP (Hyper Text Transfer Protocol) to the
59
-	    server. The server will extract the name of the function to be
60
-	    called along with its parameters from the XML document, execute the
61
-	    function, and encode any data returned by the function into another
62
-	    XML document which is then returned to the client in the body of a
63
-	    200 OK reply to the HTTP request.
64
-	</para>
65
-	<para>
66
-	    XML-RPC is similar to more popular <ulink
67
-		url="http://www.w3.org/TR/soap/">SOAP</ulink> (Simple Object
68
-		Access Protocol), which is an XML-based messaging framework
69
-		used in Web Services developed within the <ulink
70
-		url="http://www.w3c.org">World Wide Web
71
-		Consortium</ulink>. Both protocols are using HTTP as the
72
-		transport protocol for XML documents, but XML-RPC is much
73
-		simpler and easier to implement than SOAP.
74
-	</para>
75
-	<para>
76
-	    Here is an example of single XML-RPC function call to determine
77
-	    current time:
78
-	</para>
79
-	<programlisting>
80
-<![CDATA[
81
-POST /RPC2 HTTP/1.0
82
-User-Agent: Radio UserLand/7.1b7 (WinNT)
83
-Host: time.xmlrpc.com
84
-Content-Type: text/xml
85
-Content-length: 131
86
-	    
87
-<?xml version="1.0"?>
88
-<methodCall>
89
-<methodName>currentTime.getCurrentTime</methodName>
90
-<params>
91
-</params>
92
-</methodCall>
93
-]]>
94
-	</programlisting>
95
-	<para>
96
-	    And the response returned by the server:
97
-	</para>
98
-	<programlisting>
99
-<![CDATA[
100
-HTTP/1.1 200 OK
101
-Connection: close
102
-Content-Length: 183
103
-Content-Type: text/xml
104
-Date: Wed, 03 Oct 2001 15:53:38 GMT
105
-Server: UserLand Frontier/7.0.1-WinNT
106
-
107
-<?xml version="1.0"?>
108
-<methodResponse>
109
-<params>
110
-<param>
111
-<value><dateTime.iso8601>20011003T08:53:38</dateTime.iso8601>
112
-</value>
113
-</param>
114
-</params>
115
-</methodResponse>
116
-]]>
117
-	</programlisting>
118
-	<para>
119
-	    XML-RPC specification spells HTTP as the official transport
120
-	    protocol for XML-RPC documents. SER does not directly support
121
-	    HTTP, it is a SIP server so SIP is the only protocol supported by
122
-	    SER. Because we would like to reuse all transport protocols
123
-	    available in SER, such as TCP and TLS, it would be natural to use
124
-	    modified version of XML-RPC which would run on top of SIP instead
125
-	    of HTTP. XML-RPC documents would be then encoded in the bodies of
126
-	    SIP requests and replies would be sent by the server in the bodies of
127
-	    SIP replies. This way we could reuse all transport protocols
128
-	    (including UDP) and message parsers available in SER.
129
-	</para>
130
-	<para>
131
-	    Although this approach seems to be the logical choice, there is one
132
-	    big drawback. No existing XML-RPC implementations support SIP as the
133
-	    transport protocol, and there are many existing implementations
134
-	    available for vast majority of existing languages. See the <ulink
135
-	    url="http://www.xmlrpc.com/directory/1568/implementations">XML-RPC
136
-	    implementation page</ulink> for more details. Extending existing
137
-	    implementations with SIP support would not be easy.
138
-	</para>
139
-	<para>
140
-	    Because  extending available XML-RPC implementation would be too
141
-	    expensive, we could also do it the other way around, keep existing
142
-	    XML-RPC implementations and extend SER to support HTTP. Extending
143
-	    SER with HTTP support is easier than it might seem at a first
144
-	    glance, due to the similarity between SIP requests and HTTP
145
-	    requests.
146
-	</para>
147
-	<para>
148
-	    SER already supports TCP, so existing HTTP implementations can send
149
-	    HTTP requests to it. HTTP requests are missing certain mandatory
150
-	    SIP header fields, such as Via, From, and CSeq. The contents of the
151
-	    header fields is mainly used for transaction matching. A SIP server
152
-	    could perform two basic operations when processing an HTTP
153
-	    request:
154
-	    <itemizedlist>
155
-		<listitem>
156
-		    <para>
157
-			Terminate the request, execute the function and send a
158
-			reply back.
159
-		    </para>
160
-		</listitem>
161
-		<listitem>
162
-		    <para>
163
-			Forward the request to another SIP server.
164
-		    </para>
165
-		</listitem>
166
-	    </itemizedlist>
167
-	</para>
168
-	<para>
169
-	    Nothing special is needed on the SIP server terminating the
170
-	    request, except that it has to know where it should send the
171
-	    reply. Parsing of HTTP header field bodies would fail because we do
172
-	    not have parsers for them in SER, but that does not matter anyway
173
-	    because all the information is encoded in the body of the
174
-	    request. HTTP requests contain no Via header fields. Via header
175
-	    fields are used by SIP implementations to determine the destination
176
-	    (IP, transport protocol, and port number) for replies. When
177
-	    processing HTTP requests the SIP server needs to create a fake Via
178
-	    header field based on the source IP address and port number of the
179
-	    TCP connection. The SIP server will use this information when
180
-	    sending a reply back.
181
-	</para>
182
-	<para>
183
-	    Forwarding of HTTP requests by SIP proxies is a little bit more
184
-	    complicated and there are several limitations. First of all, we can
185
-	    only use stateless forwarding, no transactional forwarding, because
186
-	    HTTP requests do not contain all the header fields needed for
187
-	    transaction matching. Any attempt to call t_relay on an HTTP
188
-	    requests would fail. HTTP requests always use TCP and thus we could
189
-	    use stateless forwarding on the SIP server, provided that the
190
-	    request will be also forwarded over TCP. Stateless forwarding does
191
-	    not require the mandatory header fields (which are missing here)
192
-	    and it would work. In addition to that, the SIP server would also
193
-	    append fake Via header field to the request and change the contents
194
-	    of the Request-URI. The Request-URI of HTTP requests sent by XML-RPC
195
-	    implementations typically contain something like "/RPC2" and the
196
-	    first SIP server processing the request should rewrite the value
197
-	    with a valid SIP URI.
198
-	</para>
199
-	<para>
200
-	    <xref linkend="fig.rpc_example"/> shows a scenario which involves
201
-	    two SIP servers, one performs HTTP request "normalization" and
202
-	    forwarding, and the other terminates the request, executes
203
-	    corresponding function, and generates a reply.
20
+		The RPC (Remote Procedure Call) interface of SER is an interface for
21
+		communicating with external applications. Using it an external
22
+		application can call a function or procedure that will be executed
23
+		inside SER. Function parameters are supported as well as returning
24
+		multiple values as results.
204 25
 	</para>
205
-	<mediaobject id="fig.rpc_example" xreflabel="Figure RPC Example">
206
-	    <imageobject>
207
-		<imagedata align="center" fileref="rpc_example.png" format="PNG"/>
208
-	    </imageobject>
209
-	    <textobject>
210
-		<para>Example RPC Scenario</para>
211
-	    </textobject>
212
-	    <caption>
213
-		Example RPC Scenario
214
-	    </caption>
215
-	</mediaobject>
216 26
 	<para>
217
-	    <emphasis>Step 1.</emphasis> An HTTP user agent sends an ordinary
218
-	    HTTP request to a SIP server. The user agent can either establish a
219
-	    connection directly to port 5060 or the SIP server can be
220
-	    configured to listen on port 80. The request contains standard HTTP
221
-	    headers and an XML-RPC document in the body:
222
-	    <programlisting>
223
-<![CDATA[
224
-POST / HTTP/1.0.
225
-Host: localhost:5060
226
-User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)
227
-Content-Type: text/xml
228
-Content-Length: 111
229
-
230
-<?xml version='1.0'?>
231
-<methodCall>
232
-<methodName>]]><emphasis>usrloc.statistics</emphasis><![CDATA[</methodName>
233
-<params>
234
-</params>
235
-</methodCall>
236
-]]>
237
-	    </programlisting>
238
-	    This particular request calls method "statistics" from from usrloc
239
-	    module of SER. The method has no parameters.
240
-	</para>
241
-	<para>
242
-	    The outbound SIP server receives the HTTP request and performs a
243
-	    set of actions called "SIP-normalization". This includes creation
244
-	    of fake Via header field based on the source IP and port of the TCP
245
-	    connection, looking up of the target SIP server that should
246
-	    terminate and process the request, and rewriting of the Request-URI
247
-	    with the SIP URI of the target SIP server. Modified HTTP request
248
-	    will be then forwarded statelessly to the target SIP server.
249
-	    <programlisting>
250
-POST <emphasis>sip:proxy01.sip-server.net</emphasis> HTTP/1.0
251
-<emphasis>Via: SIP/2.0/TCP 127.0.0.1:3571</emphasis>
252
-Host: localhost:5060
253
-User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)
254
-Content-Type: text/xml
255
-Content-Length: 111
256
-<![CDATA[
257
-<?xml version='1.0'?>
258
-<methodCall>
259
-<methodName>usrloc.statistics</methodName>
260
-<params>
261
-</params>
262
-</methodCall>
263
-]]>
264
-	    </programlisting>
265
-	</para>
266
-	<para>
267
-	    <emphasis>Step 2.</emphasis> "normalized" HTTP request is
268
-	    statelessly forwarded to the target SIP server over TCP.
269
-	</para>
270
-	<para>
271
-	    <emphasis>Step 3.</emphasis> The target SIP server receives the
272
-	    HTTP request and executes function called
273
-	    <function>dispatch_rpc</function> from xmlrpc SER module. This
274
-	    function will parse the XML-RPC document in the body of the request
275
-	    and lookup the function to be called among all RPC functions
276
-	    exported by the SER core and modules. Function
277
-	    <function>dispatch_rpc</function> will be called from the
278
-	    configuration file just like any other function:
279
-	    <programlisting>
280
-if (method == "POST" || method == "GET") {
281
-    <emphasis>dispatch_rpc();</emphasis>
282
-    break;
283
-};
284
-	    </programlisting>
285
-	    This particular configuration snippet executes the function
286
-	    whenever SER receives GET or POST requests. These two method names
287
-	    indicate HTTP.
27
+		By itself SER RPC consists of two APIs, one for defining RPC functions
28
+		in a transport independent way (called the rpc module api) and one
29
+		for implementing RPC transports.
288 30
 	</para>
289 31
 	<para>
290
-	    <emphasis>Step 4.</emphasis> Function
291
-	    <function>dispatch_rpc</function> scans through the list of all
292
-	    exported RPC functions searching for
293
-	    <function>statistics</function> function of usrloc module. <xref
294
-	    linkend="rpc.module_api"/> describes in detail how modules export
295
-	    RPC functions.
32
+		The RPC transports are implemented by writting a RPC
33
+		transport module. The most used transport modules are
34
+		<ulink url='http://git.sip-router.org/cgi-bin/gitweb.cgi?p=sip-router;a=blob;f=modules_s/ctl/README'>
35
+		<emphasis>ctl</emphasis>
36
+		</ulink>
37
+		and
38
+		<ulink url='http://git.sip-router.org/cgi-bin/gitweb.cgi?p=sip-router;a=blob;f=modules_s/xmlrpc/README'>
39
+		<emphasis>xmlrpc</emphasis>
40
+		</ulink>.
41
+		The first one implements a ser-proprietary fast and space efficient
42
+		 RPC encoding over different protocols (unix sockets, UDP, TCP, fifo).
43
+		The second one uses the de-facto XML-RPC standard encoding
44
+		 (over HTTP TCP or TLS).
45
+		 For more information about the existing transport modules, please 
46
+		 refer to their documentation.
296 47
 	</para>
297 48
 	<para>
298
-	    <emphasis>Step 5.</emphasis> As the RPC function from usrloc module
299
-	    is running and gathering statistics, it calls functions of RPC
300
-	    interface to prepare the result for the caller.
49
+		When writing a SER RPC procedure or function, one needs only use the
50
+		RPC API and it will work automatically with all the transports and
51
+		encodings. One needs only to load the desired RPC transport module
52
+		(e.g. xmlrpc).
301 53
 	</para>
302 54
 	<para>
303
-	    <emphasis>Step 6.</emphasis> Once the RPC function finishes, xmlrpc
304
-	    module will build the XML-RPC document from the data received from
305
-	    usrloc module and generate a reply which will be sent to the caller.
55
+		The RPC interface (or API) was created in such a way that would allow
56
+		supporting XML-RPC (because XML-RPC is a de-facto standard), while in
57
+		the same time being very easy to use.
306 58
 	</para>
307
-	<para>
308
-	    <emphasis>Steps 7. and 8.</emphasis> HTTP reply is sent back to the
309
-	    caller and the remote procedure call finishes.
310
-	    <programlisting>
311
-<![CDATA[
312
-HTTP/1.0 200 OK
313
-Via: SIP/2.0/TCP 127.0.0.1:3571
314
-Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
315
-Content-Length: 651
316
-Warning: 392 127.0.0.1:5060 "Noisy feedback tells:  pid=9975 req_src_ip=127.0.0
317
-1 req_src_port=3571 in_uri=/ out_uri=sip:proxy01.sip-server.net via_cnt==1"
318
-
319
-<?xml version="1.0" encoding="UTF-8"?>
320
-<methodResponse>
321
-<params>
322
-<param><value><array><data>
323
-<value><struct>
324
-<member><name>domain</name>
325
-<value><string>aliases</string></value></member>
326
-<member><name>users</name>
327
-<value><i4>0</i4></value></member>
328
-<member><name>expired</name>
329
-<value><i4>0</i4></value></member>
330
-</struct></value>
331
-<value><struct>
332
-<member><name>domain</name>
333
-<value><string>location</string></value></member>
334
-<member><name>users</name>
335
-<value><i4>0</i4></value></member>
336
-<member><name>expired</name>
337
-<value><i4>0</i4></value></member>
338
-</struct></value>
339
-</data></array></value></param>
340
-</params>
341
-</methodResponse>
342
-]]>
343
-	    </programlisting>
344
-	</para>
345
-	<note>
346
-	    <para>
347
-		The scenario described on <xref linkend="fig.rpc_example"/>
348
-		involves two SIP servers. This is just to demonstrate that in
349
-		setups containing more SIP servers it is possible to forward
350
-		HTTP requests from one SIP server to another and use standard
351
-		SIP routing mechanisms to decide which SIP server should
352
-		process the request. There is no need to have multiple SIP
353
-		servers in simple setups, because one SIP server can both add 
354
-		fake Via header field and process the RPC at the same
355
-		time. Modified configuration file snipped could then look like
356
-		this:
357
-		<programlisting>
358
-if (method == "POST" || method == "GET") {
359
-    <emphasis>dispatch_rpc();</emphasis> # Process the request
360
-    break;
361
-};
362
-		</programlisting>
363
-	    </para>
364
-	</note>
365
-    </section>
59
+	</section>
366 60
 
367 61
     <section id="rpc.module_api">
368 62
 	<title>Module API</title>
... ...
@@ -371,7 +65,7 @@ if (method == "POST" || method == "GET") {
371 65
 	    parameters and functions to be called from the script. Whenever SER
372 66
 	    receives an RPC request, it will search through the list of
373 67
 	    exported RPC functions and the function with matching name will be
374
-	    executed. A couple of essential RPC functions is also embedded into
68
+	    executed. A couple of essential RPC functions are also embedded into
375 69
 	    the SER core.
376 70
 	</para>
377 71
 	<para>
... ...
@@ -414,14 +108,13 @@ typedef void (*rpc_function_t)(rpc_t* rpc);
414 108
 		indicate an error (and should not rely on RPC functions doing so).
415 109
 	    </para>
416 110
 	    <para>
417
-		The RPC transport module creates initial reply before calling
418
-		any RPC function. The default value of the reply is 200 OK with
419
-		empty body. This is the value that will be returned to the
420
-		caller and the function has to explicitly modify it if it wishes
421
-		to either indicate a failure or add some data to the reply. The
422
-		reply is sent automatically immediately after the RPC function
423
-		finishes or the function can send the reply explicitly during
424
-		its runtime. Even RPC API functions modify the reply upon a
111
+		If no reply is sent explicitely, the RPC transport module will
112
+		automatically send a "success" reply (e.g. 200 OK for XML-RPC)
113
+		when the RPC function finishes.
114
+		If no values are added to the response, the reponse will be an
115
+		empty "success" reply (e.g. a 200 OK with empty body for
116
+		XML-RPC).
117
+		RPC API functions will automatically send an error reply upon a
425 118
 		failure.
426 119
 	    </para>
427 120
 	    <para>
... ...
@@ -433,7 +126,7 @@ typedef void (*rpc_function_t)(rpc_t* rpc);
433 126
 	    </para>
434 127
 	    <para>
435 128
 		Each module containing RPC functions has to export all the
436
-		functions to SER core in order to make them visible to RPC
129
+		RPC functions to SER core in order to make them visible to RPC
437 130
 		transport modules. For this purpose, the
438 131
 		<varname>module_exports</varname> structure of SER module API
439 132
 		contains a new attribute called <varname>rpc_methods</varname>:
... ...
@@ -464,7 +157,7 @@ typedef struct rpc_export {
464 157
 		rpc_export_t structures. The last element of the array is a
465 158
 		bumper containing zeroes in all attributes of the
466 159
 		structure. The following program listing shows exported RPC
467
-		functions of usrloc module: 
160
+		functions of usrloc module:
468 161
 		<programlisting>
469 162
 struct module_exports exports = {
470 163
     "usrloc",
... ...
@@ -565,7 +258,7 @@ add("sd", string_param, int_param);
565 258
 		    is integer, float, or string. Nesting of structures is not
566 259
 		    allowed (in other words, structure attributes cannot be of
567 260
 		    type struct again). Corresponding character in the
568
-		    formatting string is "{". 
261
+		    formatting string is "{".
569 262
 		</para>
570 263
 	    </formalpara>
571 264
 	    <table>
... ...
@@ -984,301 +677,35 @@ static void rpc_register(rpc_t* rpc)
984 677
 	    </example>
985 678
 	</section>
986 679
     </section>
987
-    
988
-    <section id="rpc.xmlrpc">
989
-	<title>XML-RPC Transport</title>
990
-	<para>
991
-	    The XML-RPC transport is implemented in xmlrpc SER module. The
992
-	    purpose of the functions of the module is to convert XML-RPC
993
-	    document carried in the body of HTTP requests into data returned by
994
-	    the RPC interface and back. The module also contains functions
995
-	    necessary to "normalize" HTTP requests. The module uses <ulink
996
-		url="http://xmlrpc-c.sourceforge.net">xmlrpc-c</ulink>
997
-	    library to perform XML-RPC related functions.
998
-	</para>
680
+
681
+	<section id="rpc.client_examples">
682
+	<title>Client Examples</title>
999 683
 	<para>
1000
-	    The module always returns 200 OK HTTP reply, it will never return
1001
-	    any other HTTP reply. Failures are expressed in XML-RPC documents
1002
-	    in the body of the reply. There is basic method introspection
1003
-	    support in the module. Currently the module can list all functions
1004
-	    exported by the server and for each function it can return the
1005
-	    documentation string describing the function.
684
+	<itemizedlist>
685
+		<listitem><para>
686
+		<emphasis>sercmd</emphasis> (C application that uses the
687
+		<emphasis>binrpc</emphasis> interface implemented by the
688
+		<emphasis>ctl</emphasis> module).
689
+		</para></listitem>
690
+		<listitem><para>
691
+		<emphasis>ser_ctl</emphasis> (python application that uses the
692
+		<emphasis>XML-RPC</emphasis> interface implemented by the
693
+		<emphasis>xmlrpc</emphasis>
694
+		module).
695
+		</para></listitem>
696
+		<listitem><para>
697
+		<emphasis>serweb</emphasis> (php application that can use
698
+		the <emphasis>XML-RPC</emphasis> interface to call ser 
699
+		functions).
700
+		</para></listitem>
701
+	</itemizedlist>
1006 702
 	</para>
1007
-	<section>
1008
-	    <title>Requests</title>
1009
-	    <para>
1010
-		Requests processed by the module are standard XML-RPC requests
1011
-		encoded in bodies of HTTP requests.
1012
-		<programlisting>
1013
-<![CDATA[
1014
-POST / HTTP/1.0
1015
-Host: localhost:5060
1016
-User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)
1017
-Content-Type: text/xml
1018
-Content-Length: 112
1019
-
1020
-<?xml version='1.0'?>
1021
-<methodCall>
1022
-]]><emphasis><![CDATA[<methodName>system.listMethods</methodName>]]></emphasis><![CDATA[
1023
-<params>
1024
-</params>
1025
-</methodCall>
1026
-]]>
1027
-		</programlisting>
1028
-		The name of the method to be called in this example is
1029
-		"listMethods". This is one of the introspection methods. SER
1030
-		will call <function>dispatch_rpc</function> function of xmlrpc
1031
-		module to handle the request. The function will parse the
1032
-		XML-RPC document, lookup <function>listMethods</function>
1033
-		function in the list of all export RPC functions, prepare the
1034
-		context for the function and execute it.
1035
-	    </para>
1036
-	</section>
1037
-	<section>
1038
-	    <title>Replies</title>
1039
-	    <para>
1040
-		The module will always generate 200 OK. Other response codes
1041
-		and classes are reserved for SER. The status code of the
1042
-		XML-RPC reply, response code, and additional data will be
1043
-		encoded in the body of the reply. Failure replies do not
1044
-		contain any data, just the response code and reason phrase:
1045
-		<programlisting>
1046
-<![CDATA[
1047
-HTTP/1.0 200 OK
1048
-Via: SIP/2.0/TCP 127.0.0.1:2464
1049
-Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
1050
-Content-Length: 301
1051
-
1052
-<?xml version="1.0" encoding="UTF-8"?>
1053
-<methodResponse>
1054
-]]><emphasis><![CDATA[
1055
-<fault>
1056
-<value><struct>
1057
-<member><name>faultCode</name>
1058
-<value><i4>501</i4></value></member>
1059
-<member><name>faultString</name>
1060
-<value><string>Method Not Implemented</string></value></member>
1061
-</struct></value>
1062
-</fault>
1063
-]]></emphasis><![CDATA[
1064
-</methodResponse>
1065
-]]>
1066
-		</programlisting>
1067
-		This particular reply indicates that there is no such RPC
1068
-		method available on the server.
1069
-	    </para>
1070
-	    <para>
1071
-		Success replies always contain at least one return value. In
1072
-		our case the simplest success replies contain single boolean
1073
-		with value 1:
1074
-		<programlisting>
1075
-<![CDATA[
1076
-HTTP/1.0 200 OK
1077
-Via: SIP/2.0/TCP 127.0.0.1:4626
1078
-Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
1079
-Content-Length: 150
1080
-
1081
-<?xml version="1.0" encoding="UTF-8"?>
1082
-<methodResponse>
1083
-<params>
1084
-]]><emphasis><![CDATA[<param><value><boolean>1</boolean></value></param>]]></emphasis><![CDATA[
1085
-</params>
1086
-</methodResponse>
1087
-]]>
1088
-		</programlisting>
1089
-		This is exactly how the reply looks like when an RPC function
1090
-		does not add any data to the reply set.
1091
-	    </para>
1092
-	    <para>
1093
-		If an RPC function adds just a single item (it calls
1094
-		<function>add</function> once
1095
-		with just one character in the formatting string) then the data
1096
-		will be converted to XML-RPC representation according to the
1097
-		rules described in <xref linkend="rpc.type_conversion"/> and
1098
-		the reply will contain just the single value:
1099
-		<programlisting>
1100
-<![CDATA[
1101
-HTTP/1.0 200 OK
1102
-Via: SIP/2.0/TCP 127.0.0.1:3793
1103
-Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
1104
-Content-Length: 216
1105
-
1106
-<?xml version="1.0" encoding="UTF-8"?>
1107
-<methodResponse>
1108
-<params>
1109
-]]><emphasis><![CDATA[<param><value><string>Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))</string></value></param>]]></emphasis><![CDATA[
1110
-</params>
1111
-</methodResponse>
1112
-]]>
1113
-		</programlisting>
1114
-	    </para>
1115
-	    <para>
1116
-		If an RPC function adds more than one data items to the result
1117
-		set then the module will return an array containing all the
1118
-		data items:
1119
-		<programlisting>
1120
-<![CDATA[
1121
-HTTP/1.0 200 OK
1122
-Via: SIP/2.0/TCP 127.0.0.1:2932
1123
-Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
1124
-Content-Length: 276
1125
-
1126
-<?xml version="1.0" encoding="UTF-8"?>
1127
-<methodResponse>
1128
-<params>
1129
-<param><value>]]><emphasis><![CDATA[<array><data>
1130
-<value><string>./ser</string></value>
1131
-<value><string>-f</string></value>
1132
-<value><string>ser.cfg</string></value>
1133
-</data></array>]]></emphasis><![CDATA[</value></param>
1134
-</params>
1135
-</methodResponse>
1136
-]]>
1137
-		</programlisting>
1138
-		This is probably the most common scenario.
1139
-	    </para>
1140 703
 	</section>
1141
-	<section id="rpc.type_conversion">
1142
-	    <title>Type Conversion</title>
1143
-	    <para>
1144
-		The data types of the RPC API are converted to the data types
1145
-		of XML-RPC and vice versa. <xref
1146
-		linkend="tab.type_conversion"/> shows for each RPC API data
1147
-		type corresponding XML-RPC data type.
1148
-		<table id="tab.type_conversion">
1149
-		    <title>Data Type Conversion</title>
1150
-		    <tgroup cols="3">
1151
-			<tbody>
1152
-			    <row>
1153
-				<entry>RPC API</entry>
1154
-				<entry>XML-RPC</entry>
1155
-				<entry>RPC Example</entry>
1156
-				<entry>XML-RPC Example</entry>
1157
-			    </row>
1158
-			    <row>
1159
-				<entry>Integer</entry>
1160
-				<entry>
1161
-				    <markup role="xmlrpc">
1162
-					<![CDATA[
1163
-					<i4></i4>
1164
-					]]>
1165
-				    </markup>
1166
-				</entry>
1167
-				<entry>rpc->add("d", 42)</entry>
1168
-				<entry>
1169
-				    <markup role="xmlrpc">
1170
-					<![CDATA[
1171
-					<i4>42</i4>
1172
-					]]>
1173
-				    </markup>
1174
-				</entry>
1175
-			    </row>
1176
-			    <row>
1177
-				<entry>Float</entry>
1178
-				<entry>
1179
-				    <markup role="xmlrpc">
1180
-					<![CDATA[
1181
-					<double></double>
1182
-					]]>
1183
-				    </markup>
1184
-				</entry>
1185
-				<entry>rpc->add("f", -12.214)</entry>
1186
-				<entry>
1187
-				    <markup role="xmlrpc">
1188
-					<![CDATA[
1189
-					<double>-12.214</double>
1190
-					]]>
1191
-				    </markup>
1192
-				</entry>
1193
-			    </row>
1194
-			    <row>
1195
-				<entry>String</entry>
1196
-				<entry>
1197
-				    <markup role="xmlrpc">
1198
-					<![CDATA[
1199
-					<string></string>
1200
-					]]>
1201
-				    </markup>
1202
-				</entry>
1203
-				<entry>rpc->add("s","Don't panic")</entry>
1204
-				<entry>
1205
-				    <markup role="xmlrpc">
1206
-					<![CDATA[
1207
-					<string>Don't panic</string>
1208
-					]]>
1209
-				    </markup>
1210
-				</entry>
1211
-			    </row>
1212
-			    <row>
1213
-				<entry>Struct</entry>
1214
-				<entry>
1215
-				    <markup role="xmlrpc">
1216
-					<![CDATA[
1217
-					<struct></struct>
1218
-					]]>
1219
-				    </markup>
1220
-				</entry>
1221
-				<entry>rpc->struct_add(handle,"sd","param1",42,"param2",-12.214)</entry>
1222
-				<entry>
1223
-				    <programlisting>
1224
-<![CDATA[
1225
-<struct>
1226
-  <member>
1227
-    <name>param1</name>
1228
-    <value>
1229
-      <i4>42</i4>
1230
-    </value>
1231
-  </member>
1232
-  <member>
1233
-    <name>param2</name>
1234
-    <value>
1235
-      <double>-12.214</i4>
1236
-    </value>
1237
-  </member>
1238
-</struct>
1239
-]]>
1240
-				    </programlisting>
1241
-				</entry>
1242
-			    </row>
1243
-			</tbody>
1244
-		    </tgroup>
1245
-		</table>
1246
-	    </para>
1247
-	</section>
1248
-	<section>
1249
-	    <title>Limitations</title>
1250
-	    <para>
1251
-		SER xmlrpc modules does not implement all data types allowed in
1252
-		XML-RPC. As well it does not implement arrays and nested
1253
-		structures. This simplification is a feature, not bug. In our
1254
-		case the XML-RPC interface will be used mainly for management
1255
-		purposes and we do not need all the bells and whistles of
1256
-		XML-RPC. Parsing and interpreting nested structures is
1257
-		complex and we try to avoid it.
1258
-	    </para>
1259
-	</section>
1260
-    </section>
1261
-
1262
-    <section>
1263
-	<title>Client Examples</title>
1264
-	To be done.
1265
-	<!--
1266
-	    implement clients in various languages 
1267
-	- pros, cons 
1268
-	- How failures
1269
-	    are mapped to XMLRPC 
1270
-	- How success replies are mapped 
1271
-	- How data
1272
-	    types of the API are mapped to XMLRPC elements 
1273
-	- 200 OK with no
1274
-	    data transformed to one value - True
1275
-	-->
1276
-    </section>
1277 704
 
1278 705
     <section id="rpc.new_transport">
1279 706
 	<title>Implementing New Transports</title>
1280 707
 	To be done.
1281
-	<!--
708
+	<!-- TODO:
1282 709
 	- create a new module
1283 710
 	- take a look at sip_router/rpc.h
1284 711
 	- implement all functions in that header field
... ...
@@ -1293,5 +720,24 @@ Content-Length: 276
1293 720
 	- no structure/array nesting allowed
1294 721
 	- printf creates string attribute
1295 722
         -->
723
+	<para>
724
+		Examples:
725
+		<itemizedlist>
726
+			<listitem><para>
727
+				<emphasis>ctl</emphasis>
728
+			</para></listitem>
729
+			<listitem><para>
730
+				<emphasis>xmlrpc</emphasis>
731
+			</para></listitem>
732
+		</itemizedlist>
733
+	</para>
1296 734
     </section>
735
+
736
+<section id="rpc.xmlrpc_examples">
737
+	<title>Examples using xmlrpc</title>
738
+	<para>See the <varname>xmlrpc</varname> module documentation:
739
+	<ulink url='http://git.sip-router.org/cgi-bin/gitweb.cgi?p=sip-router;a=blob;f=modules_s/xmlrpc/README'>modules_s/xmlrpc/README</ulink>.
740
+	</para>
741
+</section>
742
+
1297 743
 </section>
1298 744
new file mode 100644
... ...
@@ -0,0 +1,4 @@
1
+docs = xmlrpc.xml
2
+
3
+docbook_dir=../../../docbook
4
+include $(docbook_dir)/Makefile.module
0 5
similarity index 100%
1 6
rename from doc/rpc/rpc_example.dia
2 7
rename to modules_s/xmlrpc/doc/rpc_example.dia
3 8
similarity index 100%
4 9
rename from doc/rpc/rpc_example.png
5 10
rename to modules_s/xmlrpc/doc/rpc_example.png
6 11
new file mode 100644
... ...
@@ -0,0 +1,689 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
3
+	"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
4
+
5
+<section id="xmlrpc" xmlns:xi="http://www.w3.org/2001/XInclude">
6
+    <sectioninfo>
7
+	<authorgroup>
8
+		<author>
9
+		<firstname>Jan</firstname>
10
+		<surname>Janak</surname>
11
+		<affiliation><orgname>iptelorg GmbH</orgname></affiliation>
12
+		<address>
13
+			<email>jan@iptel.org</email>
14
+		</address>
15
+		</author>
16
+	</authorgroup>
17
+	<copyright>
18
+		<year>2005</year>
19
+		<holder>iptelorg GmbH</holder>
20
+	</copyright>
21
+	<revhistory>
22
+		<revision>
23
+		<revnumber>$Revision$</revnumber>
24
+		<date>$Date$</date>
25
+		</revision>
26
+	</revhistory>
27
+	</sectioninfo>
28
+
29
+
30
+	<section id="xmlrpc.design">
31
+	<title>Design Goals</title>
32
+	<para>
33
+	    
34
+	</para>
35
+	<itemizedlist>
36
+	    <listitem>
37
+		<para>Implemented as a module.</para>
38
+	    </listitem>
39
+	    <listitem>
40
+		<para>API independent of transport protocols.</para>
41
+	    </listitem>
42
+	    <listitem>
43
+		<para>Reuse transports available in SER.</para>
44
+	    </listitem>
45
+	    <listitem>
46
+		<para>The possibility to encrypt all communication.</para>
47
+	    </listitem>
48
+	    <listitem>
49
+		<para>The possibility to authenticate clients.</para>
50
+	    </listitem>
51
+	    <listitem>
52
+		<para>Easy integration with existing languages and
53
+		    implementations.</para>
54
+	    </listitem>
55
+	    <listitem>
56
+		<para>
57
+		    Easy and straightforward implementation of management
58
+		    functions in SER modules.
59
+		</para>
60
+	    </listitem>
61
+	</itemizedlist>
62
+	</section>
63
+
64
+	<section id="xmlrpc.overview">
65
+	<title>Overview of Operation</title>
66
+	<para>
67
+		This module implements the XML-RPC transport and encoding interface
68
+		for ser RPCs.
69
+	</para>
70
+	<para>
71
+	    The XML-RPC protocol encodes the name of the method
72
+	    to be called along with its parameter in an XML document which is
73
+	    then conveyed using HTTP (Hyper Text Transfer Protocol) to the
74
+	    server. The server will extract the name of the function to be
75
+	    called along with its parameters from the XML document, execute the
76
+	    function, and encode any data returned by the function into another
77
+	    XML document which is then returned to the client in the body of a
78
+	    200 OK reply to the HTTP request.
79
+	</para>
80
+	<para>
81
+	    XML-RPC is similar to more popular <ulink
82
+		url="http://www.w3.org/TR/soap/">SOAP</ulink> (Simple Object
83
+		Access Protocol), which is an XML-based messaging framework
84
+		used in Web Services developed within the <ulink
85
+		url="http://www.w3c.org">World Wide Web
86
+		Consortium</ulink>. Both protocols are using HTTP as the
87
+		transport protocol for XML documents, but XML-RPC is much
88
+		simpler and easier to implement than SOAP.
89
+	</para>
90
+	<para>
91
+	    Here is an example of single XML-RPC function call to determine
92
+	    current time:
93
+	</para>
94
+	<programlisting>
95
+<![CDATA[
96
+POST /RPC2 HTTP/1.0
97
+User-Agent: Radio UserLand/7.1b7 (WinNT)
98
+Host: time.xmlrpc.com
99
+Content-Type: text/xml
100
+Content-length: 131
101
+	    
102
+<?xml version="1.0"?>
103
+<methodCall>
104
+<methodName>currentTime.getCurrentTime</methodName>
105
+<params>
106
+</params>
107
+</methodCall>
108
+]]>
109
+	</programlisting>
110
+	<para>
111
+	    And the response returned by the server:
112
+	</para>
113
+	<programlisting>
114
+<![CDATA[
115
+HTTP/1.1 200 OK
116
+Connection: close
117
+Content-Length: 183
118
+Content-Type: text/xml
119
+Date: Wed, 03 Oct 2001 15:53:38 GMT
120
+Server: UserLand Frontier/7.0.1-WinNT
121
+
122
+<?xml version="1.0"?>
123
+<methodResponse>
124
+<params>
125
+<param>
126
+<value><dateTime.iso8601>20011003T08:53:38</dateTime.iso8601>
127
+</value>
128
+</param>
129
+</params>
130
+</methodResponse>
131
+]]>
132
+	</programlisting>
133
+	<para>
134
+	    XML-RPC specification spells HTTP as the official transport
135
+	    protocol for XML-RPC documents. SER does not directly support
136
+	    HTTP, it is a SIP server so SIP is the only protocol supported by
137
+	    SER. Because we would like to reuse all transport protocols
138
+	    available in SER, such as TCP and TLS, it would be natural to use
139
+	    modified version of XML-RPC which would run on top of SIP instead
140
+	    of HTTP. XML-RPC documents would be then encoded in the bodies of
141
+	    SIP requests and replies would be sent by the server in the bodies of
142
+	    SIP replies. This way we could reuse all transport protocols
143
+	    (including UDP) and message parsers available in SER.
144
+	</para>
145
+	<para>
146
+	    Although this approach seems to be the logical choice, there is one
147
+	    big drawback. No existing XML-RPC implementations support SIP as the
148
+	    transport protocol, and there are many existing implementations
149
+	    available for vast majority of existing languages. See the <ulink
150
+	    url="http://www.xmlrpc.com/directory/1568/implementations">XML-RPC
151
+	    implementation page</ulink> for more details. Extending existing
152
+	    implementations with SIP support would not be easy.
153
+	</para>
154
+	<para>
155
+	    Because  extending available XML-RPC implementation would be too
156
+	    expensive, we could also do it the other way around, keep existing
157
+	    XML-RPC implementations and extend SER to support HTTP. Extending
158
+	    SER with HTTP support is easier than it might seem at a first
159
+	    glance, due to the similarity between SIP requests and HTTP
160
+	    requests.
161
+	</para>
162
+	<para>
163
+	    SER already supports TCP, so existing HTTP implementations can send
164
+	    HTTP requests to it. HTTP requests are missing certain mandatory
165
+	    SIP header fields, such as Via, From, and CSeq. The contents of the
166
+	    header fields is mainly used for transaction matching. A SIP server
167
+	    could perform two basic operations when processing an HTTP
168
+	    request:
169
+	    <itemizedlist>
170
+		<listitem>
171
+		    <para>
172
+			Terminate the request, execute the function and send a
173
+			reply back.
174
+		    </para>
175
+		</listitem>
176
+		<listitem>
177
+		    <para>
178
+			Forward the request to another SIP server.
179
+		    </para>
180
+		</listitem>
181
+	    </itemizedlist>
182
+	</para>
183
+	<para>
184
+	    Nothing special is needed on the SIP server terminating the
185
+	    request, except that it has to know where it should send the
186
+	    reply. Parsing of HTTP header field bodies would fail because we do
187
+	    not have parsers for them in SER, but that does not matter anyway
188
+	    because all the information is encoded in the body of the
189
+	    request. HTTP requests contain no Via header fields. Via header
190
+	    fields are used by SIP implementations to determine the destination
191
+	    (IP, transport protocol, and port number) for replies. When
192
+	    processing HTTP requests the SIP server needs to create a fake Via
193
+	    header field based on the source IP address and port number of the
194
+	    TCP connection. The SIP server will use this information when
195
+	    sending a reply back.
196
+	</para>
197
+	<para>
198
+	    Forwarding of HTTP requests by SIP proxies is a little bit more
199
+	    complicated and there are several limitations. First of all, we can
200
+	    only use stateless forwarding, no transactional forwarding, because
201
+	    HTTP requests do not contain all the header fields needed for
202
+	    transaction matching. Any attempt to call t_relay on an HTTP
203
+	    requests would fail. HTTP requests always use TCP and thus we could
204
+	    use stateless forwarding on the SIP server, provided that the
205
+	    request will be also forwarded over TCP. Stateless forwarding does
206
+	    not require the mandatory header fields (which are missing here)
207
+	    and it would work. In addition to that, the SIP server would also
208
+	    append fake Via header field to the request and change the contents
209
+	    of the Request-URI. The Request-URI of HTTP requests sent by XML-RPC
210
+	    implementations typically contain something like "/RPC2" and the
211
+	    first SIP server processing the request should rewrite the value
212
+	    with a valid SIP URI.
213
+	</para>
214
+	<para>
215
+	    <xref linkend="fig.rpc_example"/> shows a scenario which involves
216
+	    two SIP servers, one performs HTTP request "normalization" and
217
+	    forwarding, and the other terminates the request, executes
218
+	    corresponding function, and generates a reply.
219
+	</para>
220
+	<mediaobject id="fig.rpc_example" xreflabel="Figure RPC Example">
221
+	    <imageobject>
222
+		<imagedata align="center" fileref="rpc_example.png" format="PNG"/>
223
+	    </imageobject>
224
+	    <textobject>
225
+		<para>Example RPC Scenario</para>
226
+	    </textobject>
227
+	    <caption>
228
+		Example RPC Scenario
229
+	    </caption>
230
+	</mediaobject>
231
+	<para>
232
+	    <emphasis>Step 1.</emphasis> An HTTP user agent sends an ordinary
233
+	    HTTP request to a SIP server. The user agent can either establish a
234
+	    connection directly to port 5060 or the SIP server can be
235
+	    configured to listen on port 80. The request contains standard HTTP
236
+	    headers and an XML-RPC document in the body:
237
+	    <programlisting>
238
+<![CDATA[
239
+POST / HTTP/1.0.
240
+Host: localhost:5060
241
+User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)
242
+Content-Type: text/xml
243
+Content-Length: 111
244
+
245
+<?xml version='1.0'?>
246
+<methodCall>
247
+<methodName>]]><emphasis>usrloc.statistics</emphasis><![CDATA[</methodName>
248
+<params>
249
+</params>
250
+</methodCall>
251
+]]>
252
+	    </programlisting>
253
+	    This particular request calls method "statistics" from from usrloc
254
+	    module of SER. The method has no parameters.
255
+	</para>
256
+	<para>
257
+	    The outbound SIP server receives the HTTP request and performs a
258
+	    set of actions called "SIP-normalization". This includes creation
259
+	    of fake Via header field based on the source IP and port of the TCP
260
+	    connection, looking up of the target SIP server that should
261
+	    terminate and process the request, and rewriting of the Request-URI
262
+	    with the SIP URI of the target SIP server. Modified HTTP request
263
+	    will be then forwarded statelessly to the target SIP server.
264
+	    <programlisting>
265
+POST <emphasis>sip:proxy01.sip-server.net</emphasis> HTTP/1.0
266
+<emphasis>Via: SIP/2.0/TCP 127.0.0.1:3571</emphasis>
267
+Host: localhost:5060
268
+User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)
269
+Content-Type: text/xml
270
+Content-Length: 111
271
+<![CDATA[
272
+<?xml version='1.0'?>
273
+<methodCall>
274
+<methodName>usrloc.statistics</methodName>
275
+<params>
276
+</params>
277
+</methodCall>
278
+]]>
279
+	    </programlisting>
280
+	</para>
281
+	<para>
282
+	    <emphasis>Step 2.</emphasis> "normalized" HTTP request is
283
+	    statelessly forwarded to the target SIP server over TCP.
284
+	</para>
285
+	<para>
286
+	    <emphasis>Step 3.</emphasis> The target SIP server receives the
287
+	    HTTP request and executes function called
288
+	    <function>dispatch_rpc</function> from xmlrpc SER module. This
289
+	    function will parse the XML-RPC document in the body of the request
290
+	    and lookup the function to be called among all RPC functions
291
+	    exported by the SER core and modules. Function
292
+	    <function>dispatch_rpc</function> will be called from the
293
+	    configuration file just like any other function:
294
+	    <programlisting>
295
+if (method == "POST" || method == "GET") {
296
+    <emphasis>dispatch_rpc();</emphasis>
297
+    break;
298
+};
299
+	    </programlisting>
300
+	    This particular configuration snippet executes the function
301
+	    whenever SER receives GET or POST requests. These two method names
302
+	    indicate HTTP.
303
+	</para>
304
+	<para>
305
+	    <emphasis>Step 4.</emphasis> Function
306
+	    <function>dispatch_rpc</function> scans through the list of all
307
+	    exported RPC functions searching for
308
+	    <function>statistics</function> function of usrloc module. The
309
+		<ulink url='http://git.sip-router.org/cgi-bin/gitweb.cgi?p=sip-router;a=blob;f=doc/rpc/ser_rpc.txt'>
310
+		SER RPC Module API</ulink>
311
+		describes in detail how modules export RPC functions.
312
+	</para>
313
+	<para>
314
+	    <emphasis>Step 5.</emphasis> As the RPC function from usrloc module
315
+	    is running and gathering statistics, it calls functions of RPC
316
+	    interface to prepare the result for the caller.
317
+	</para>
318
+	<para>
319
+	    <emphasis>Step 6.</emphasis> Once the RPC function finishes, xmlrpc
320
+	    module will build the XML-RPC document from the data received from
321
+	    usrloc module and generate a reply which will be sent to the caller.
322
+	</para>
323
+	<para>
324
+	    <emphasis>Steps 7. and 8.</emphasis> HTTP reply is sent back to the
325
+	    caller and the remote procedure call finishes.
326
+	    <programlisting>
327
+<![CDATA[
328
+HTTP/1.0 200 OK
329
+Via: SIP/2.0/TCP 127.0.0.1:3571
330
+Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
331
+Content-Length: 651
332
+Warning: 392 127.0.0.1:5060 "Noisy feedback tells:  pid=9975 req_src_ip=127.0.0
333
+1 req_src_port=3571 in_uri=/ out_uri=sip:proxy01.sip-server.net via_cnt==1"
334
+
335
+<?xml version="1.0" encoding="UTF-8"?>
336
+<methodResponse>
337
+<params>
338
+<param><value><array><data>
339
+<value><struct>
340
+<member><name>domain</name>
341
+<value><string>aliases</string></value></member>
342
+<member><name>users</name>
343
+<value><i4>0</i4></value></member>
344
+<member><name>expired</name>
345
+<value><i4>0</i4></value></member>
346
+</struct></value>
347
+<value><struct>
348
+<member><name>domain</name>
349
+<value><string>location</string></value></member>
350
+<member><name>users</name>
351
+<value><i4>0</i4></value></member>
352
+<member><name>expired</name>
353
+<value><i4>0</i4></value></member>
354
+</struct></value>
355
+</data></array></value></param>
356
+</params>
357
+</methodResponse>
358
+]]>
359
+	    </programlisting>
360
+	</para>
361
+	<note>
362
+	    <para>
363
+		The scenario described on <xref linkend="fig.rpc_example"/>
364
+		involves two SIP servers. This is just to demonstrate that in
365
+		setups containing more SIP servers it is possible to forward
366
+		HTTP requests from one SIP server to another and use standard
367
+		SIP routing mechanisms to decide which SIP server should
368
+		process the request. There is no need to have multiple SIP
369
+		servers in simple setups, because one SIP server can both add 
370
+		fake Via header field and process the RPC at the same
371
+		time. Modified configuration file snipped could then look like
372
+		this:
373
+		<programlisting>
374
+if (method == "POST" || method == "GET") {
375
+    <emphasis>dispatch_rpc();</emphasis> # Process the request
376
+    break;
377
+};
378
+		</programlisting>
379
+	    </para>
380
+	</note>
381
+    </section>
382
+
383
+
384
+
385
+	<section id="xmlrpc.implementation">
386
+	<title>XML-RPC Implementation</title>
387
+	<para>
388
+	    The purpose of the functions of this module is to convert XML-RPC
389
+	    document carried in the body of HTTP requests into data returned by
390
+	    the RPC interface and back. The module also contains functions
391
+	    necessary to "normalize" HTTP requests. The module uses <ulink
392
+		url="http://xmlrpc-c.sourceforge.net">xmlrpc-c</ulink>
393
+	    library to perform XML-RPC related functions.
394
+	</para>
395
+	<para>
396
+	    The module always returns 200 OK HTTP reply, it will never return
397
+	    any other HTTP reply. Failures are expressed in XML-RPC documents
398
+	    in the body of the reply. There is basic method introspection
399
+	    support in the module. Currently the module can list all functions
400
+	    exported by the server and for each function it can return the
401
+	    documentation string describing the function.
402
+	</para>
403
+	<section id="xmlrpc.implementation.requests">
404
+	    <title>Requests</title>
405
+	    <para>
406
+		Requests processed by the module are standard XML-RPC requests
407
+		encoded in bodies of HTTP requests.
408
+		<programlisting>
409
+<![CDATA[
410
+POST / HTTP/1.0
411
+Host: localhost:5060
412
+User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)
413
+Content-Type: text/xml
414
+Content-Length: 112
415
+
416
+<?xml version='1.0'?>
417
+<methodCall>
418
+]]><emphasis><![CDATA[<methodName>system.listMethods</methodName>]]></emphasis><![CDATA[
419
+<params>
420
+</params>
421
+</methodCall>
422
+]]>
423
+		</programlisting>
424
+		The name of the method to be called in this example is
425
+		"listMethods". This is one of the introspection methods. SER
426
+		will call <function>dispatch_rpc</function> function of xmlrpc
427
+		module to handle the request. The function will parse the
428
+		XML-RPC document, lookup <function>listMethods</function>
429
+		function in the list of all export RPC functions, prepare the
430
+		context for the function and execute it.
431
+	    </para>
432
+	</section>
433
+	<section id="xmlrpc.implementation.replies">
434
+	    <title>Replies</title>
435
+	    <para>
436
+		The module will always generate 200 OK. Other response codes
437
+		and classes are reserved for SER. The status code of the
438
+		XML-RPC reply, response code, and additional data will be
439
+		encoded in the body of the reply. Failure replies do not
440
+		contain any data, just the response code and reason phrase:
441
+		<programlisting>
442
+<![CDATA[
443
+HTTP/1.0 200 OK
444
+Via: SIP/2.0/TCP 127.0.0.1:2464
445
+Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
446
+Content-Length: 301
447
+
448
+<?xml version="1.0" encoding="UTF-8"?>
449
+<methodResponse>
450
+]]><emphasis><![CDATA[
451
+<fault>
452
+<value><struct>
453
+<member><name>faultCode</name>
454
+<value><i4>501</i4></value></member>
455
+<member><name>faultString</name>
456
+<value><string>Method Not Implemented</string></value></member>
457
+</struct></value>
458
+</fault>
459
+]]></emphasis><![CDATA[
460
+</methodResponse>
461
+]]>
462
+		</programlisting>
463
+		This particular reply indicates that there is no such RPC
464
+		method available on the server.
465
+	    </para>
466
+	    <para>
467
+		Success replies always contain at least one return value. In
468
+		our case the simplest success replies contain single boolean
469
+		with value 1:
470
+		<programlisting>
471
+<![CDATA[
472
+HTTP/1.0 200 OK
473
+Via: SIP/2.0/TCP 127.0.0.1:4626
474
+Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
475
+Content-Length: 150
476
+
477
+<?xml version="1.0" encoding="UTF-8"?>
478
+<methodResponse>
479
+<params>
480
+]]><emphasis><![CDATA[<param><value><boolean>1</boolean></value></param>]]></emphasis><![CDATA[
481
+</params>
482
+</methodResponse>
483
+]]>
484
+		</programlisting>
485
+		This is exactly how the reply looks like when an RPC function
486
+		does not add any data to the reply set.
487
+	    </para>
488
+	    <para>
489
+		If an RPC function adds just a single item (it calls
490
+		<function>add</function> once
491
+		with just one character in the formatting string) then the data
492
+		will be converted to XML-RPC representation according to the
493
+		rules described in
494
+		<ulink url='http://git.sip-router.org/cgi-bin/gitweb.cgi?p=sip-router;a=blob;f=doc/rpc/ser_rpc.txt'>
495
+		SER RPC Type Converion</ulink> and
496
+		the reply will contain just the single value:
497
+		<programlisting>
498
+<![CDATA[
499
+HTTP/1.0 200 OK
500
+Via: SIP/2.0/TCP 127.0.0.1:3793
501
+Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
502
+Content-Length: 216
503
+
504
+<?xml version="1.0" encoding="UTF-8"?>
505
+<methodResponse>
506
+<params>
507
+]]><emphasis><![CDATA[<param><value><string>Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))</string></value></param>]]></emphasis><![CDATA[
508
+</params>
509
+</methodResponse>
510
+]]>
511
+		</programlisting>
512
+	    </para>
513
+	    <para>
514
+		If an RPC function adds more than one data items to the result
515
+		set then the module will return an array containing all the
516
+		data items:
517
+		<programlisting>
518
+<![CDATA[
519
+HTTP/1.0 200 OK
520
+Via: SIP/2.0/TCP 127.0.0.1:2932
521
+Server: Sip EXpress router (0.10.99-janakj_experimental (i386/linux))
522
+Content-Length: 276
523
+
524
+<?xml version="1.0" encoding="UTF-8"?>
525
+<methodResponse>
526
+<params>
527
+<param><value>]]><emphasis><![CDATA[<array><data>
528
+<value><string>./ser</string></value>
529
+<value><string>-f</string></value>
530
+<value><string>ser.cfg</string></value>
531
+</data></array>]]></emphasis><![CDATA[</value></param>
532
+</params>
533
+</methodResponse>
534
+]]>
535
+		</programlisting>
536
+		This is probably the most common scenario.
537
+	    </para>
538
+	</section>
539
+	<section id="xmlrpc.implementation.type_conversion">
540
+	    <title>Type Conversion</title>
541
+	    <para>
542
+		The data types of the RPC API are converted to the data types
543
+		of XML-RPC and vice versa. <xref
544
+		linkend="tab.type_conversion"/> shows for each RPC API data
545
+		type corresponding XML-RPC data type.
546
+		<table id="tab.type_conversion">
547
+		    <title>Data Type Conversion</title>
548
+		    <tgroup cols="3">
549
+			<tbody>
550
+			    <row>
551
+				<entry>RPC API</entry>
552
+				<entry>XML-RPC</entry>
553
+				<entry>RPC Example</entry>
554
+				<entry>XML-RPC Example</entry>
555
+			    </row>
556
+			    <row>
557
+				<entry>Integer</entry>
558
+				<entry>
559
+				    <markup role="xmlrpc">
560
+					<![CDATA[
561
+					<i4></i4>
562
+					]]>
563
+				    </markup>
564
+				</entry>
565
+				<entry>rpc->add("d", 42)</entry>
566
+				<entry>
567
+				    <markup role="xmlrpc">
568
+					<![CDATA[
569
+					<i4>42</i4>
570
+					]]>
571
+				    </markup>
572
+				</entry>
573
+			    </row>
574
+			    <row>
575
+				<entry>Float</entry>
576
+				<entry>
577
+				    <markup role="xmlrpc">
578
+					<![CDATA[
579
+					<double></double>
580
+					]]>