Browse code

doc: rpc txt version added

ser_rpc.txt generated from ser_rpc.xml added.

Andrei Pelinescu-Onciul authored on 11/05/2009 14:51:42
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,523 @@
0
+1.  SER Management Interface
1
+     __________________________________________________________________
2
+
3
+   1.1. Overview of Operation
4
+   1.2. Module API
5
+
6
+        1.2.1. RPC Functions
7
+        1.2.2. Data Types
8
+        1.2.3. Getting Parameters
9
+
10
+              1.2.3.1. scan
11
+              1.2.3.2. struct_scan
12
+
13
+        1.2.4. Building Reply
14
+
15
+              1.2.4.1. fault
16
+              1.2.4.2. send
17
+              1.2.4.3. add
18
+              1.2.4.4. printf
19
+              1.2.4.5. struct_add
20
+
21
+        1.2.5. Real World Example
22
+
23
+   1.3. Client Examples
24
+   1.4. Implementing New Transports
25
+   1.5. Examples using xmlrpc
26
+
27
+1.1. Overview of Operation
28
+
29
+   The RPC (Remote Procedure Call) interface of SER is an interface for
30
+   communicating with external applications. Using it an external
31
+   application can call a function or procedure that will be executed
32
+   inside SER. Function parameters are supported as well as returning
33
+   multiple values as results.
34
+
35
+   By itself SER RPC consists of two APIs, one for defining RPC functions
36
+   in a transport independent way (called the rpc module api) and one for
37
+   implementing RPC transports.
38
+
39
+   The RPC transports are implemented by writting a RPC transport module.
40
+   The most used transport modules are ctl and xmlrpc . The first one
41
+   implements a ser-proprietary fast and space efficient RPC encoding over
42
+   different protocols (unix sockets, UDP, TCP, fifo). The second one uses
43
+   the de-facto XML-RPC standard encoding (over HTTP TCP or TLS). For more
44
+   information about the existing transport modules, please refer to their
45
+   documentation.
46
+
47
+   When writing a SER RPC procedure or function, one needs only use the
48
+   RPC API and it will work automatically with all the transports and
49
+   encodings. One needs only to load the desired RPC transport module
50
+   (e.g. xmlrpc).
51
+
52
+   The RPC interface (or API) was created in such a way that would allow
53
+   supporting XML-RPC (because XML-RPC is a de-facto standard), while in
54
+   the same time being very easy to use.
55
+
56
+1.2. Module API
57
+
58
+   Each SER module can export RPC functions just like it can export
59
+   parameters and functions to be called from the script. Whenever SER
60
+   receives an RPC request, it will search through the list of exported
61
+   RPC functions and the function with matching name will be executed. A
62
+   couple of essential RPC functions are also embedded into the SER core.
63
+
64
+   This section gives a detailed overview of the whole RPC API.
65
+   Section 1.2.1, "RPC Functions" describes the prototype and conventions
66
+   used in RPC functions. Section 1.2.2, "Data Types" gives a detailed
67
+   overview of available data types that can be used in function
68
+   parameters and return value. Section 1.2.3, "Getting Parameters"
69
+   describes functions of the RPC API that can be used to retrieve
70
+   parameters of the function, and finally Section 1.2.4, "Building Reply"
71
+   describes functions of the API that can be used to build the result
72
+   value that will be sent in the reply to the caller.
73
+
74
+   The whole RPC API is described in header file sip_router/rpc.h. This
75
+   file defines the set of functions that must be implemented by RPC
76
+   transport modules, as described in Section 1.4, "Implementing New
77
+   Transports", prototypes of RPC functions and structures used for the
78
+   communication between RPC transport modules and ordinary modules
79
+   exporting RPC functions.
80
+
81
+1.2.1. RPC Functions
82
+
83
+   RPC functions are standard C functions with the following prototype:
84
+typedef void (*rpc_function_t)(rpc_t* rpc);
85
+
86
+   RPC functions take one parameter, this parameter is a pointer to rpc_t
87
+   structure and is called RPC context. The context contains references to
88
+   all API functions available to the RPC function as well as all data
89
+   necessary to create the response. RPC functions do not return any
90
+   value, instead the return value is created using functions from the
91
+   context. The motivation for this decision is the fact that RPC
92
+   functions should always return a response and even the API functions
93
+   called from RPC functions should have the possibility to indicate an
94
+   error (and should not rely on RPC functions doing so).
95
+
96
+   If no reply is sent explicitely, the RPC transport module will
97
+   automatically send a "success" reply (e.g. 200 OK for XML-RPC) when the
98
+   RPC function finishes. If no values are added to the response, the
99
+   reponse will be an empty "success" reply (e.g. a 200 OK with empty body
100
+   for XML-RPC). RPC API functions will automatically send an error reply
101
+   upon a failure.
102
+
103
+   Each RPC function has associated an array of documentation strings. The
104
+   purpose of the documentation strings is to give a short overview of the
105
+   function, accepted parameters, and format of the reply. By convention
106
+   the name of the documentation string array is same as the name of the
107
+   function with "_doc" suffix.
108
+
109
+   Each module containing RPC functions has to export all the RPC
110
+   functions to SER core in order to make them visible to RPC transport
111
+   modules. For this purpose, the module_exports structure of SER module
112
+   API contains a new attribute called rpc_methods:
113
+struct module_exports {
114
+    char* name;                 /* null terminated module name */
115
+    cmd_export_t* cmds;         /* null terminated array of the exported command
116
+s */
117
+    rpc_export_t* rpc_methods;  /* null terminated array of exported rpc methods
118
+ */
119
+    param_export_t* params;     /* null terminated array of the exported module
120
+parameters */
121
+
122
+    init_function init_f;         /* Initialization function */
123
+    response_function response_f; /* function used for responses */
124
+    destroy_function destroy_f;   /* function called upon SER shutdown */
125
+    onbreak_function onbreak_f;
126
+    child_init_function init_child_f;  /* function called by all processes after
127
+ the fork */
128
+};
129
+
130
+
131
+typedef struct rpc_export {
132
+    const char* name;        /* Name of the RPC function (null terminated) */
133
+    rpc_function_t function; /* Pointer to the function */
134
+    const char** doc_str;    /* Documentation strings, method signature and desc
135
+ription */
136
+    unsigned int flags;      /* Various flags, reserved for future use */
137
+} rpc_export_t;
138
+
139
+   rpc_methods is pointer to an array of rpc_export_t structures. The last
140
+   element of the array is a bumper containing zeroes in all attributes of
141
+   the structure. The following program listing shows exported RPC
142
+   functions of usrloc module:
143
+struct module_exports exports = {
144
+    "usrloc",
145
+    cmds,      /* Exported functions */
146
+    ul_rpc,    /* RPC methods */
147
+    params,    /* Export parameters */
148
+    mod_init,  /* Module initialization function */
149
+    0,         /* Response function */
150
+    destroy,   /* Destroy function */
151
+    0,         /* OnCancel function */
152
+    child_init /* Child initialization function */ };
153
+
154
+
155
+rpc_export_t ul_rpc[] = {
156
+    {"usrloc.statistics",      rpc_stats,           rpc_stats_doc,          0},
157
+    {"usrloc.delete_aor",      rpc_delete_aor,      rpc_delete_aor_doc,     0},
158
+    {"usrloc.delete_contact",  rpc_delete_contact,  rpc_delete_contact_doc, 0},
159
+    {"usrloc.dump",            rpc_dump,            rpc_dump_doc,           0},
160
+    {"usrloc.flush",           rpc_flush,           rpc_flush_doc,          0},
161
+    {"usrloc.add_contact",     rpc_add_contact,     rpc_add_contact_doc,    0},
162
+    {"usrloc.show_contacts",   rpc_show_contacts,   rpc_show_contacts_doc,  0},
163
+    {0, 0, 0, 0}
164
+};
165
+
166
+   By convention the name of every exported function consists of two parts
167
+   delimited by a dot. The first part is the name of the module or SER
168
+   subsystem this function belongs to. The second part is the name of the
169
+   function.
170
+
171
+   Attribute flags of rpc_export structure is reserved for future use and
172
+   is currently unused.
173
+
174
+1.2.2. Data Types
175
+
176
+   The RPC API defines several basic and 1 compound data type that can be
177
+   used in communication with the caller of RPC functions. The RPC API
178
+   uses formating strings to describe data types. Each data type is
179
+   described by exactly one character in the formating string. For
180
+   example, if an RPC function calls function add of the RPC API and it
181
+   passes two parameters to it, the first one of type string and the
182
+   second one of type integer, the function parameters will look like:
183
+add("sd", string_param, int_param);
184
+
185
+   Character "s" in the formating string tells to the function that the
186
+   2nd parameter should be interpreted as string, character "d" in the
187
+   formating string tells to the function that the 3rd parameter should be
188
+   interpreted as signed integer.
189
+
190
+   Integer.  Integer type represents a signed 32-bit integer.
191
+   Corresponding character in the formating string is "d". This parameter
192
+   can be stored in C-style variable with type int.
193
+
194
+   Float.  Float type represents a signed floating point number.
195
+   Corresponding character in the formating string is "f". Data of this
196
+   type can be stored in C-style variables of type double.
197
+
198
+   String.  String type represents a string of characters. The string may
199
+   contain zeroes. This data type is represented by two characters in the
200
+   formatting string, either "s" or "S". "s" indicates to the conversion
201
+   function that the result should be stored in a variable of type char*
202
+   and it should be zero terminated. "S" indicates to the conversion
203
+   function that the result will be stored in a variable of type str which
204
+   contains both the pointer to the beginning of the string and its
205
+   length.
206
+
207
+   Structure.  Structure is the only compound data type currently defined
208
+   in the API. A structure is a collection of attributes. Each attribute
209
+   is identified using name (string) and each attribute can be one of the
210
+   basic data types, that is integer, float, or string. Nesting of
211
+   structures is not allowed (in other words, structure attributes cannot
212
+   be of type struct again). Corresponding character in the formatting
213
+   string is "{".
214
+
215
+   Table 1. Data Type Overview
216
+   Name    Formating String Char C-Style Variable
217
+   Integer d                     int
218
+   Float   f                     double
219
+   String  s                     char*
220
+   String  S                     str
221
+
222
+1.2.3. Getting Parameters
223
+
224
+   Each RPC function call can contain parameters. Parameters have no name,
225
+   their meaning is determined by their position in the parameter set.
226
+
227
+Note
228
+
229
+   You can pass all parameters to a function within a structure if you
230
+   want to make them position independent. Then each parameter can be
231
+   retrieved by its name regardless of its position.
232
+
233
+   There are two functions in the RPC API that can be used to obtain
234
+   function call parameters: scan and struct_scan.
235
+
236
+1.2.3.1. scan
237
+
238
+   Function scan can be used to retrieve parameters from the parameter
239
+   set. The function accepts variable number of parameters. The first
240
+   parameter is the formatting string that determines the type of the
241
+   parameters to be retrieved. Each parameter is represented by exactly
242
+   one character in the string. The variable part of parameters must
243
+   contain as many pointers to C variables as there are formatting
244
+   characters in the formatting string.
245
+
246
+Warning
247
+
248
+   The function will crash if you fail to provide enough parameters.
249
+
250
+   The function indicates success by returning 0. When a failure occurs
251
+   (incorrect parameter type or no more parameters in the parameter set)
252
+   then the function will return -1 and it will also automatically change
253
+   the reply that will be sent to the caller to indicate that a failure
254
+   has occurred on the server. Prototype of the function is:
255
+int scan(char* fmt, ...)
256
+
257
+   It is possible to either call the function once to scan all the
258
+   parameters:
259
+rpc->scan("sdf", &string_val, &int_val, &double_val);
260
+
261
+   Or you can call the same function several times and it will continue
262
+   where it left off previously:
263
+rpc->scan("s", &string_val);
264
+rpc->scan("d", &int_val);
265
+rpc->scan("f", &double_val);
266
+
267
+1.2.3.2. struct_scan
268
+
269
+   Function struct_scan can be used to retrieve named attributes from a
270
+   parameter of type structure. When retrieving a structure parameter from
271
+   the parameter set:
272
+rpc->scan("{", &handle);
273
+
274
+   The corresponding variable (named handlein the example above) will
275
+   contain the index of the structure parameter within the parameter set,
276
+   but the index cannot be used to retrieve the contents of the structure.
277
+   To retrieve the contents of the structure you can use function
278
+   struct_scan. The function gets the handle as the first parameter:
279
+rpc->struct_scan(handle, "sd", "str_attr", &str_val, "int_attr", &int_val);
280
+
281
+   The second parameter is the formatting string followed by pairs of
282
+   parameters. First parameter in each pair is the name of the attribute
283
+   to retrieve (string) and the second parameter in each pair is the
284
+   pointer to the variable to store the value of the parameter. The
285
+   function returns 0 on success and -1 on an error (just like scan
286
+   function). The function also indicates an error if a requested
287
+   attribute is missing in the structure.
288
+
289
+   Example 1. Retrieving Parameters
290
+static void rpc_delete_contact(rpc_t* rpc)
291
+{
292
+    str aor, contact;
293
+    char* table;
294
+    void *handle;
295
+    int   expires;
296
+    double q;
297
+
298
+    if (rpc->scan("sS{", &table, &aor, &handle) < 0) {
299
+        /* Reply is set automatically by scan upon failure,
300
+         * no need to do anything here
301
+         */
302
+        return;
303
+    }
304
+
305
+    if (rpc->struct_scan(handle, "Sdf", &contact, &expires, &q) < 0) {
306
+        /* Reply is set automatically by struct_scan upon failure,
307
+         * no need to do anything here
308
+         */
309
+        return;
310
+    }
311
+
312
+    /* Process retrieved parameters here */
313
+}
314
+
315
+1.2.4. Building Reply
316
+
317
+   The RPC API contains several functions that can be used to modify
318
+   and/or send a reply. The functions use formatting strings and parameter
319
+   lists just like functions described in Section 1.2.3, "Getting
320
+   Parameters".
321
+
322
+   Each RPC function call must return a reply. The reply can be either a
323
+   failure reply or success reply. Failure replies contain only the status
324
+   code and reason phrase. Success replies can have arbitrary amount of
325
+   data attached to them. Status codes 3xx, 4xx, 5xx, and 6xx indicate
326
+   failures. Status code 2xx indicates success.
327
+
328
+   The default reply is 200 OK with no data attached to it. This is what
329
+   will be returned by the RPC transport module if you do not call any of
330
+   the reply-related functions described in this section.
331
+
332
+   Example 2. Sending default reply
333
+static void rpc_dummy(rpc_t* rpc)
334
+{
335
+  /* 200 OK with no data will be returned */
336
+}
337
+
338
+1.2.4.1. fault
339
+
340
+   You can use fault function to indicate that an error has occurred on
341
+   the server to the caller. The function accepts two parameters. The
342
+   first parameter is the status code and the second parameter is the
343
+   reason phrase.
344
+static void rpc_my_function(rpc_t* rpc)
345
+{
346
+    rpc->fault(600, "Not Yet Implemented");
347
+}
348
+
349
+   If your function first creates some result using add, or printf
350
+   functions then all the data will be lost once you call fault function.
351
+   Failure replies must not contain any data:
352
+static void rpc_my_function(rpc_t* rpc)
353
+{
354
+    rpc->add("s", "result1");
355
+    rpc->add("d", variable);
356
+
357
+    /* Reply created by previous functions will be
358
+     * deleted and a failure reply 600 Not Yet Implemented
359
+     * will be created instead
360
+     */
361
+    rpc->fault(600, "Not Yet Implemented");
362
+
363
+    /* You can also add data here, but that will have no
364
+     * effect
365
+     */
366
+    rpc->add("s", "result2");
367
+}
368
+
369
+   Similarly you can also call add or printf functions after calling
370
+   fault, in this case they will have no effect:
371
+static void rpc_my_function(rpc_t* rpc)
372
+{
373
+    rpc->fault(600, "Not Yet Implemented");
374
+
375
+    /* You can also add data here, but that will have no
376
+     * effect and only 600 Not Yet Implemented will be returned
377
+     */
378
+    rpc->add("s", "result2");
379
+}
380
+
381
+1.2.4.2. send
382
+
383
+   RPC functions can use function send to explicitly send the reply. Each
384
+   RPC function call generates exactly one reply. No reply will be sent
385
+   after the function finishes if it already sent the reply using send
386
+   function explicitly. This function is especially useful if the RPC
387
+   function needs to perform some (potentially destructive) actions after
388
+   the reply has been sent.
389
+
390
+   Example 3. Kill the server
391
+static void core_kill(rpc_t* rpc)
392
+{
393
+    int sig_no;
394
+
395
+    if (rpc->scan("d", &sig_no) < 0) return;
396
+    rpc->send();     /* First send a reply */
397
+    kill(0, sig_no); /* Then kill the server */
398
+}
399
+
400
+1.2.4.3. add
401
+
402
+   Function add can be used to add arbitrary data to the result set. Its
403
+   parameters and use are analogical to scan function described in
404
+   Section 1.2.3.1, "scan". The first parameter of the function is the
405
+   formatting string that determines the types of additional parameters:
406
+static void rpc_func(rpc_t* rpc)
407
+{
408
+    str str_result;
409
+    int int_result;
410
+    void *handle;
411
+    double float_result;
412
+
413
+    if (rpc->add("Sdf{", &str_result, int_result, float_result, &handle) < 0) re
414
+turn;
415
+}
416
+
417
+   Naturally you can call this function several times, adding only one
418
+   piece of data at a time. The function returns 0 on success and -1 on an
419
+   error. In case of an error the reply is set automatically with
420
+   corresponding error code and reason phrase.
421
+
422
+   The last character in the formatting string of the function above
423
+   indicates that the last data to be added will be a structure. This
424
+   deserves some clarification. In this case, the function will create an
425
+   empty structure and the handle to the newly created structure will be
426
+   stored in handle variable (hence the last parameter is pointer to an
427
+   integer). In this particular example parameters str_result, int_result,
428
+   and float_result will be used for reading while parameter handle will
429
+   be used for writing by the function.
430
+
431
+   You can set the attributes of the newly created structure using
432
+   struct_add function described in Section 1.2.4.5, "struct_add".
433
+
434
+1.2.4.4. printf
435
+
436
+   printf is a convenience function. The function adds data of type string
437
+   to the result set. The first parameter of the function is again a
438
+   formatting string, but this time it is printf-like formatting string:
439
+if (rpc->printf("Unable to delete %d entries from table %s", num_entries, table_
440
+name) < 0) return;
441
+
442
+   The return value of the function is the same as of add function.
443
+
444
+1.2.4.5. struct_add
445
+
446
+   Function struct_add can be used to add attributes to a structure
447
+   (created previously by add function). The first parameter of the
448
+   function is handle obtained through add function, the second parameters
449
+   is formatting string that determines the types of attributes to be
450
+   added. There must be two parameters per each character in the
451
+   formatting string, the first one is the name of the attribute, the
452
+   second parameter is the value of the attribute. If a parameter with
453
+   such a name already exist in the structure then it will be overwritten
454
+   with the new value.
455
+static void rpc_func(rpc_t* rpc)
456
+{
457
+    void *handle;
458
+
459
+        /* Create empty structure and obtain its handle */
460
+    if (rpc->add("{", &handle) < 0) return;
461
+        /* Fill-in the structure */
462
+    if (rpc->struct_add(handle, "sd", "attr1", str_val, "attr2", int_val) < 0) r
463
+eturn;
464
+}
465
+
466
+   The function returns -1 on an error (and sets the status code and
467
+   reason phrase of the reply accordingly) and 0 on success.
468
+
469
+1.2.5. Real World Example
470
+
471
+   The following example illustrates the use of most of the functions from
472
+   the API together:
473
+
474
+   Example 4. Real World Example RPC Function
475
+static void rpc_register(rpc_t* rpc)
476
+{
477
+    char* domain;
478
+    str aor;
479
+    contact_t contact, new_contact;
480
+    void *handle;
481
+
482
+        /* Extract the domain, address of record from the request */
483
+    if (rpc->scan("sS{", &domain, &aor, &handle) < 0) return;
484
+        /* Extract the structure describing the contact to be processed */
485
+    if (rpc->struct_scan(handle, "Sdf", &contact.c, &contact.expires, &contact.q
486
+) < 0) return;
487
+
488
+        /* Process the contact, new_contact will contain updated value after pro
489
+cessing */
490
+    if (process_contact(domain, &aor, &new_contact, &contact) < 0) {
491
+           /* Processing failed, indicate the failure to the caller */
492
+        rpc->fault(500, "Error While Processing Contact");
493
+        return;
494
+    }
495
+
496
+        /* Return the domain and the address of record */
497
+    rpc->add("sS{", &domain, &aor, &handle) < 0) return;
498
+        /* And also add the new values for contact, q, and expires parameters */
499
+    rpc->struct_add(handle, "Sdf", &new_contact.c, &new_contact.expires, &new_co
500
+ntact.q);
501
+}
502
+
503
+1.3. Client Examples
504
+
505
+     * sercmd (C application that uses the binrpc interface implemented by
506
+       the ctl module).
507
+     * ser_ctl (python application that uses the XML-RPC interface
508
+       implemented by the xmlrpc module).
509
+     * serweb (php application that can use the XML-RPC interface to call
510
+       ser functions).
511
+
512
+1.4. Implementing New Transports
513
+
514
+   To be done.
515
+
516
+   Examples:
517
+     * ctl
518
+     * xmlrpc
519
+
520
+1.5. Examples using xmlrpc
521
+
522
+   See the xmlrpc module documentation: modules_s/xmlrpc/README.