|
1 <?xml version="1.0" encoding="UTF-8"?> |
|
2 <!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> |
|
3 <!-- |
|
4 PDL HEADER START |
|
5 |
|
6 Public Documentation License Notice |
|
7 |
|
8 The contents of this Documentation are subject to the Public |
|
9 Documentation License Version 1.01 (the "License"); you may only |
|
10 use this Documentation if you comply with the terms of this License. |
|
11 A copy of the License is available at |
|
12 http://www.opensolaris.org/os/community/documentation/license. |
|
13 |
|
14 PDL HEADER END |
|
15 |
|
16 Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
|
17 --> |
|
18 |
|
19 <appendix xmlns:rm="rad-macros"> |
|
20 <title><command>rad</command> binary protocol</title> |
|
21 |
|
22 <!-- |
|
23 While it's not a very traditional way to document binary protocols, |
|
24 BNF might be a clearer way to communicate some of the optional |
|
25 paths. We should consider adding it as an addition to the textual / |
|
26 diagrammatical description. |
|
27 --> |
|
28 |
|
29 <para> |
|
30 In addition to supporting multiple transports, <command>rad</command> |
|
31 is capable of talking different protocols. The default (and currently |
|
32 only) protocol is a proprietary binary protocol designated |
|
33 <literal>rad</literal>. This appendix documents version 1 of this |
|
34 protocol. |
|
35 </para> |
|
36 |
|
37 <section><title>Overview</title> |
|
38 <para> |
|
39 The <literal>rad</literal> protocol is a bi-directional binary protocol |
|
40 that operates over a single stream. Communication in both directions |
|
41 takes the form of discrete messages. These messages are framed using |
|
42 <acronym>RPC</acronym> record marking (See <quote>RECORD MARKING |
|
43 STANDARD</quote> in <citation>RPC</citation>). |
|
44 </para> |
|
45 |
|
46 <para> |
|
47 The individual messages take the formats documented below. Even though |
|
48 <acronym>RPC</acronym> record marking permits skipping messages of |
|
49 unknown format, both the client and the server are free to immediately |
|
50 drop the connection when an invalid message is seen. |
|
51 </para> |
|
52 |
|
53 <para> |
|
54 The <literal>rad</literal> protocol is built using |
|
55 <citation>XDR</citation>, so for simplicity and clarity the |
|
56 <acronym>XDR</acronym> primitive type names and syntax will be used |
|
57 throughout this appendix. For example: |
|
58 </para> |
|
59 |
|
60 <itemizedlist> |
|
61 <listitem> |
|
62 <quote><literal>FOO<></literal></quote> would represent a |
|
63 variable-length array of <literal>FOO</literal>s, communicated as |
|
64 an <literal>unsigned int</literal> containing the size followed by |
|
65 that number of <literal>FOO</literal>s. |
|
66 </listitem> |
|
67 <listitem> |
|
68 <quote><literal>FOO[n]</literal></quote> would represent a |
|
69 fixed-length array of a predetermined size, communicated only as |
|
70 the <literal>n</literal> <literal>FOO</literal>s. |
|
71 </listitem> |
|
72 <listitem> |
|
73 <quote><literal>FOO *</literal></quote> would represent an optional |
|
74 value, communicated as a <literal>boolean</literal> value followed |
|
75 by a <literal>FOO</literal> if and only if the |
|
76 <literal>boolean</literal> value was true. |
|
77 </listitem> |
|
78 </itemizedlist> |
|
79 |
|
80 </section> |
|
81 |
|
82 <section><title>Common data formats</title> |
|
83 <para> |
|
84 There are a few types and concepts that appear repeatedly |
|
85 throughout the <literal>rad</literal> protocol. They are described |
|
86 here. |
|
87 </para> |
|
88 |
|
89 <section id="op-data-def"><title>Operations</title> |
|
90 <para> |
|
91 The various operations one can perform against the server are |
|
92 communicated with an operation code. |
|
93 </para> |
|
94 |
|
95 <rm:proto name="OP-CODE"> |
|
96 <rm:data field="op_code" size="4" type="int"> |
|
97 <rm:codedef label="operation" prefix="oc"> |
|
98 <rm:code num="0" name="INVOKE" /> |
|
99 <rm:code num="1" name="GETATTR" /> |
|
100 <rm:code num="2" name="SETATTR" /> |
|
101 <rm:code num="3" name="LOOKUP" /> |
|
102 <rm:code num="4" name="DEFINE" /> |
|
103 <rm:code num="5" name="LIST" /> |
|
104 <rm:code num="6" name="SUB" /> |
|
105 <rm:code num="7" name="UNSUB" /> |
|
106 </rm:codedef> |
|
107 </rm:data> |
|
108 </rm:proto> |
|
109 </section> |
|
110 |
|
111 <section id="error-data-def"><title>Errors</title> |
|
112 <para> |
|
113 Errors in the <literal>rad</literal> protocol are communicated by |
|
114 an error code, and optionally structured error data. |
|
115 </para> |
|
116 |
|
117 <rm:proto name="ERROR-CODE"> |
|
118 <rm:data field="error_code" size="4" type="int"> |
|
119 <rm:codedef label="error" prefix="ec"> |
|
120 <rm:code num="0" name="ok" /> |
|
121 <rm:code num="1" name="object" /> |
|
122 <rm:code num="2" name="nomem" /> |
|
123 <rm:code num="3" name="notfound" /> |
|
124 <rm:code num="4" name="priv" /> |
|
125 <rm:code num="5" name="system" /> |
|
126 <rm:code num="6" name="exists" /> |
|
127 <rm:code num="7" name="mismatch" /> |
|
128 <rm:code num="8" name="illegal" /> |
|
129 </rm:codedef> |
|
130 </rm:data> |
|
131 </rm:proto> |
|
132 |
|
133 <para> |
|
134 For object-specific errors, <literal>EC-OBJECT</literal>, the |
|
135 format of the structured data is defined by the object's interface |
|
136 definition. For the remainder, save for <literal>EC-OK</literal> |
|
137 (which is defined for completeness, but should never appear in the |
|
138 protocol), the format is defined during the initial connection |
|
139 handshake. See <xref linkend="proto-handshake" />. |
|
140 </para> |
|
141 </section> |
|
142 |
|
143 <section id="time-data-def"><title>Time</title> |
|
144 <para> |
|
145 When a time needs to be represented in the <literal>rad</literal> |
|
146 protocol, it is communicated as seconds and nanoseconds offset from |
|
147 the epoch (January 1, 1970 UTC). |
|
148 </para> |
|
149 |
|
150 <para> |
|
151 It is important to note that the accuracy of such time data is |
|
152 determined by its context. In most, if not all, cases, the full |
|
153 nanosecond precision is only relevant when compared to time data |
|
154 obtained from the same host. |
|
155 </para> |
|
156 |
|
157 <rm:proto name="TIME-DATA"> |
|
158 <rm:data field="secs" size="8" type="hyper"> |
|
159 number of seconds |
|
160 </rm:data> |
|
161 <rm:data field="nsecs" size="4" type="int"> |
|
162 number of nanoseconds (<mathphrase>0 ≤ nsec ≤ |
|
163 10<superscript>9</superscript></mathphrase>) |
|
164 </rm:data> |
|
165 </rm:proto> |
|
166 </section> |
|
167 |
|
168 <section id="name-data-def"><title>Object names</title> |
|
169 <para> |
|
170 <command>rad</command> object names are structured, consisting of a |
|
171 domain and one or more key-value pairs. When an object name or |
|
172 pattern needs to be represented in the <literal>rad</literal> |
|
173 protocol, this structure is flattened to a canonical string |
|
174 format. This string format consists of the domain, followed by a |
|
175 colon (':'), followed by comma-separated key-value pairs. Each |
|
176 key-value pair consists of the name, followed by an equals sign |
|
177 ('='), followed by the value. |
|
178 </para> |
|
179 |
|
180 <para> |
|
181 Because keys and values may contain the special characters '=' or |
|
182 ',', a quoting algorithm is applied when constructing the string. |
|
183 The following substitutions are applied to keys and values: |
|
184 </para> |
|
185 |
|
186 <table><title>Object Name Escaping</title> |
|
187 <tgroup cols='2'> |
|
188 <thead> |
|
189 <row><entry>Plain Text</entry><entry>Escaped Text</entry></row> |
|
190 </thead> |
|
191 <tbody> |
|
192 <row><entry>\</entry><entry>\S</entry></row> |
|
193 <row><entry>,</entry><entry>\C</entry></row> |
|
194 <row><entry>=</entry><entry>\E</entry></row> |
|
195 </tbody> |
|
196 </tgroup> |
|
197 </table> |
|
198 |
|
199 <para> |
|
200 Note that under this transformation, backslashes are only found as |
|
201 part of quoted characters, and commas and equals signs, when |
|
202 present, always have their special meaning. Object names that use |
|
203 no special characters are passed through unchanged. These facts |
|
204 can be used to simplify parsing or preprocessing of |
|
205 string-formatted object names. |
|
206 </para> |
|
207 |
|
208 <rm:proto name="NAME-DATA"> |
|
209 <rm:data field="name" size="variable" type="string<>"> |
|
210 flattened object name |
|
211 </rm:data> |
|
212 </rm:proto> |
|
213 |
|
214 <example> |
|
215 An object name in the domain <quote>com.example</quote> with the |
|
216 following keys and values: |
|
217 |
|
218 <informaltable> |
|
219 <tgroup cols='2'> |
|
220 <thead> |
|
221 <row><entry>Key</entry><entry>Value</entry></row> |
|
222 </thead> |
|
223 <tbody> |
|
224 <row><entry>directory</entry><entry>C:\</entry></row> |
|
225 <row><entry>first,last</entry><entry>Doe,John</entry></row> |
|
226 </tbody> |
|
227 </tgroup> |
|
228 </informaltable> |
|
229 |
|
230 would be represented by the string |
|
231 <quote>com.example:directory=C:\S,first\Clast=Doe\CJohn</quote>. |
|
232 </example> |
|
233 </section> |
|
234 |
|
235 <section id="adr-data"><title><acronym>ADR</acronym> data</title> |
|
236 <para> |
|
237 Central to the <literal>rad</literal> protocol is the communication |
|
238 of data defined by <acronym>ADR</acronym>. Most |
|
239 <acronym>ADR</acronym> primitives map directly to |
|
240 <acronym>XDR</acronym> types: |
|
241 </para> |
|
242 |
|
243 <table> |
|
244 <title>Primitive <acronym>ADR</acronym> to Wire Type Mapping</title> |
|
245 <tgroup cols='2'> |
|
246 <thead> |
|
247 <row> |
|
248 <entry><acronym>ADR</acronym> Type</entry> |
|
249 <entry>Wire Type</entry> |
|
250 </row> |
|
251 </thead> |
|
252 <tbody> |
|
253 <row> |
|
254 <entry>boolean</entry> |
|
255 <entry><acronym>XDR</acronym> <literal>boolean</literal></entry> |
|
256 </row> |
|
257 <row> |
|
258 <entry>integer</entry> |
|
259 <entry><acronym>XDR</acronym> <literal>int</literal></entry> |
|
260 </row> |
|
261 <row> |
|
262 <entry>uinteger</entry> |
|
263 <entry><acronym>XDR</acronym> <literal>unsigned int</literal></entry> |
|
264 </row> |
|
265 <row> |
|
266 <entry>long</entry> |
|
267 <entry><acronym>XDR</acronym> <literal>hyper</literal></entry> |
|
268 </row> |
|
269 <row> |
|
270 <entry>ulong</entry> |
|
271 <entry><acronym>XDR</acronym> <literal>unsigned hyper</literal></entry> |
|
272 </row> |
|
273 <row> |
|
274 <entry>float</entry> |
|
275 <entry><acronym>XDR</acronym> <literal>float</literal></entry> |
|
276 </row> |
|
277 <row> |
|
278 <entry>double</entry> |
|
279 <entry><acronym>XDR</acronym> <literal>double</literal></entry> |
|
280 </row> |
|
281 <row> |
|
282 <entry>string</entry> |
|
283 <entry><acronym>XDR</acronym> <literal>string<></literal></entry> |
|
284 </row> |
|
285 <row> |
|
286 <entry>opaque</entry> |
|
287 <entry><acronym>XDR</acronym> <literal>opaque<></literal></entry> |
|
288 </row> |
|
289 <row> |
|
290 <entry>password</entry> |
|
291 <entry><acronym>XDR</acronym> <literal>string<></literal></entry> |
|
292 </row> |
|
293 <row> |
|
294 <entry>time</entry> |
|
295 <entry><literal>TIME-DATA</literal> |
|
296 (see <xref linkend="time-data-def" />)</entry> |
|
297 </row> |
|
298 <row> |
|
299 <entry>name</entry> |
|
300 <entry><literal>NAME-DATA</literal> |
|
301 (see <xref linkend="name-data-def" />)</entry> |
|
302 </row> |
|
303 </tbody> |
|
304 </tgroup> |
|
305 </table> |
|
306 |
|
307 <para> |
|
308 Optional <acronym>ADR</acronym> data of any type is represented as |
|
309 <acronym>XDR</acronym> optional data. |
|
310 </para> |
|
311 |
|
312 <rm:proto name="OPTIONAL-DATA"> |
|
313 <rm:data field="data" size="varies" type="ADR-DATA *"> |
|
314 Optional encoded data |
|
315 </rm:data> |
|
316 </rm:proto> |
|
317 |
|
318 <para> |
|
319 Array data is communicated as an <acronym>XDR</acronym> array of |
|
320 the element data. That is, it is represented by an |
|
321 <acronym>XDR</acronym> <literal>unsigned int</literal> whose value |
|
322 is the number of array elements, followed by that number of element |
|
323 data. |
|
324 </para> |
|
325 |
|
326 <rm:proto name="ARRAY-DATA"> |
|
327 <rm:data field="elements" size="varies" type="ADR-DATA<>"> |
|
328 array elements |
|
329 </rm:data> |
|
330 </rm:proto> |
|
331 |
|
332 <para> |
|
333 Structure data is communicated by communicating each structure |
|
334 field in the order they are defined. This may consist of a mixture |
|
335 of optional and non-optional data. |
|
336 </para> |
|
337 |
|
338 <rm:proto name="STRUCT-DATA"> |
|
339 <rm:data field="fields" size="varies" type="ADR-DATA[n]"> |
|
340 fixed-length array of structure fields |
|
341 (n = type-defined field count) |
|
342 </rm:data> |
|
343 </rm:proto> |
|
344 |
|
345 <para> |
|
346 Enumeration data is communicated as an <acronym>XDR</acronym> |
|
347 <literal>unsigned int</literal> whose value is the 1-based index |
|
348 into the list of enumerated values (i.e. 1 would be the first |
|
349 enumerated value, n would be the nth enumerated value). A value of |
|
350 0 represents the fallback value. For enumerations without a |
|
351 fallback value, the 0 value is unused. |
|
352 </para> |
|
353 |
|
354 <rm:proto name="ENUM-DATA"> |
|
355 <rm:data field="value" size="4" type="unsigned int"> |
|
356 0 if fallback, 1-based index otherwise |
|
357 </rm:data> |
|
358 </rm:proto> |
|
359 |
|
360 <para> |
|
361 Union data is communicated as an <acronym>XDR</acronym> |
|
362 <literal>unsigned int</literal> whose value is the 1-based index |
|
363 into the list of union arms. A value of 0 represents the default |
|
364 arm. When a non-default arm is selected, the arm is followed by |
|
365 that arm's data. When the default arm is selected, it is first |
|
366 followed by the discriminant data value, and then is followed by |
|
367 the default arm's data. |
|
368 </para> |
|
369 |
|
370 <rm:proto name="UNION-DATA (non default)"> |
|
371 <rm:data field="arm_index" size="4" type="unsigned int"> |
|
372 1-based index into list of arms |
|
373 </rm:data> |
|
374 <rm:data field="arm_data" size="varies" type="ADR-DATA"> |
|
375 Arm data |
|
376 </rm:data> |
|
377 </rm:proto> |
|
378 |
|
379 <rm:proto name="UNION-DATA (default)"> |
|
380 <rm:data field="arm_index" size="4" type="unsigned int"> |
|
381 0 |
|
382 </rm:data> |
|
383 <rm:data field="discriminant" size="4" type="ENUM-DATA | boolean"> |
|
384 discriminant value |
|
385 </rm:data> |
|
386 <rm:data field="arm_data" size="varies" type="ADR-DATA"> |
|
387 Arm data |
|
388 </rm:data> |
|
389 </rm:proto> |
|
390 |
|
391 </section> |
|
392 |
|
393 <!-- Consider switching this section and the previous section --> |
|
394 <section><title><acronym>ADR</acronym> types</title> |
|
395 <para> |
|
396 As discussed in <xref linkend="adr-data" />, the |
|
397 <acronym>ADR</acronym> data communicated by the |
|
398 <literal>rad</literal> protocol has a structure determined by its |
|
399 type. Before that data can be communicated to the client, however, |
|
400 the types themselves must be communicated. |
|
401 </para> |
|
402 |
|
403 <para> |
|
404 For efficiency, type data is communicated using a system of type |
|
405 spaces and type references. A type space is an array of type |
|
406 definitions that is referenced by a protocol-defined set of |
|
407 consumers. A consumer referring to a type will use a type |
|
408 reference, which points to either a primitive type or to an element |
|
409 of the type space. |
|
410 </para> |
|
411 |
|
412 <para> |
|
413 Both type references and type spaces need to refer to the various |
|
414 types. They do this using an integral type code: |
|
415 </para> |
|
416 |
|
417 <rm:proto name="TYPE-CODE"> |
|
418 <rm:data field="type_code" size="4" type="int"> |
|
419 <rm:codedef label="type" prefix="tc"> |
|
420 <rm:code num="0" name="void" /> |
|
421 <rm:code num="1" name="boolean" /> |
|
422 <rm:code num="2" name="integer" /> |
|
423 <rm:code num="3" name="uinteger" /> |
|
424 <rm:code num="4" name="long" /> |
|
425 <rm:code num="5" name="ulong" /> |
|
426 <rm:code num="6" name="float" /> |
|
427 <rm:code num="7" name="double" /> |
|
428 <rm:code num="8" name="time" /> |
|
429 <rm:code num="9" name="string" /> |
|
430 <rm:code num="10" name="opaque" /> |
|
431 <rm:code num="11" name="password" /> |
|
432 <rm:code num="12" name="name" /> |
|
433 <rm:code num="13" name="enum" /> |
|
434 <rm:code num="14" name="array" /> |
|
435 <rm:code num="15" name="struct" /> |
|
436 <rm:code num="16" name="union" /> |
|
437 </rm:codedef> |
|
438 </rm:data> |
|
439 </rm:proto> |
|
440 |
|
441 <para> |
|
442 Concretely, a type reference consists of an XDR int whose value is |
|
443 one of the above type constants. If the type is an enum, array, |
|
444 union, or struct, the type reference also includes an XDR int whose |
|
445 value is an index into the current type space: |
|
446 </para> |
|
447 |
|
448 <rm:proto name="TYPEREF (basic type)"> |
|
449 <rm:data field="type_code" size="4" type="TYPE-CODE"> |
|
450 a primitive type code |
|
451 </rm:data> |
|
452 </rm:proto> |
|
453 |
|
454 <rm:proto name="TYPEREF (derived type)"> |
|
455 <rm:data field="type_code" size="4" type="TYPE-CODE"> |
|
456 <literal>TC-ENUM</literal>, <literal>TC-ARRAY</literal>, |
|
457 <literal>TC-STRUCT</literal>, or <literal>TC-UNION</literal> |
|
458 </rm:data> |
|
459 <rm:data field="type_index" size="4" type="int"> |
|
460 type space index |
|
461 </rm:data> |
|
462 </rm:proto> |
|
463 |
|
464 <para> |
|
465 A type space is a topologically sorted array of type definitions. |
|
466 A derived type may only reference derived types defined earlier in |
|
467 the type space. That is, a type reference used by the type at |
|
468 index <mathphrase>X</mathphrase> may only reference a primitive |
|
469 type or a derived type a index less than |
|
470 <mathphrase>X</mathphrase>. Recursively defined types are not |
|
471 supported. |
|
472 </para> |
|
473 |
|
474 <para> |
|
475 Apart from a common distinguishing type code, each derived type is |
|
476 defined differently. Arrays are the simplest. An array definition |
|
477 consists of only a reference to the element type: |
|
478 </para> |
|
479 |
|
480 <rm:proto name="ARRAY-TYPE"> |
|
481 <rm:data field="type_code" size="4" type="TYPE-CODE"> |
|
482 <literal>TC-ARRAY</literal> |
|
483 </rm:data> |
|
484 <rm:data field="element_type" size="varies" type="TYPEREF"> |
|
485 the element type |
|
486 </rm:data> |
|
487 </rm:proto> |
|
488 |
|
489 <para> |
|
490 A structure type definition consists of a name and an array of |
|
491 field definitions. The order in which the fields are specified in |
|
492 <literal>STRUCT-TYPE</literal> is the order used to serialize the |
|
493 fields in <literal>STRUCT-DATA</literal>. |
|
494 </para> |
|
495 |
|
496 <rm:proto name="FIELD-TYPE"> |
|
497 <rm:data field="name" size="varies" type="string<>"> |
|
498 the field name |
|
499 </rm:data> |
|
500 <rm:data field="optional" size="4" type="boolean"> |
|
501 is the field value optional? |
|
502 </rm:data> |
|
503 <rm:data field="type" size="varies" type="TYPEREF"> |
|
504 the field type |
|
505 </rm:data> |
|
506 </rm:proto> |
|
507 |
|
508 <rm:proto name="STRUCT-TYPE"> |
|
509 <rm:data field="type_code" size="4" type="TYPE-CODE"> |
|
510 <literal>TC-STRUCT</literal> |
|
511 </rm:data> |
|
512 <rm:data field="name" size="varies" type="string<>"> |
|
513 the structure name |
|
514 </rm:data> |
|
515 <rm:data field="fields" size="varies" type="FIELD-TYPE<>"> |
|
516 ordered list of structure fields |
|
517 </rm:data> |
|
518 </rm:proto> |
|
519 |
|
520 <para> |
|
521 A union type definition consists of a name, a reference to the |
|
522 discriminant type, optionally a default arm specification, and an |
|
523 array of arm definitions. The arm index referenced by |
|
524 <literal>UNION-DATA</literal> is an index into the array of arms |
|
525 defined by the corresponding <literal>UNION-TYPE</literal>. |
|
526 </para> |
|
527 |
|
528 <rm:proto name="ARM-TYPE"> |
|
529 <rm:data field="value" size="4" type="ENUM-DATA | boolean"> |
|
530 the discriminant value that selects this arm |
|
531 </rm:data> |
|
532 <rm:data field="optional" size="4" type="boolean"> |
|
533 is the arm's value optional? |
|
534 </rm:data> |
|
535 <rm:data field="type" size="varies" type="TYPEREF"> |
|
536 the arm's type |
|
537 </rm:data> |
|
538 </rm:proto> |
|
539 |
|
540 <rm:proto name="UNION-TYPE (without default arm)"> |
|
541 <rm:data field="type_code" size="4" type="TYPE-CODE"> |
|
542 <literal>TC-UNION</literal> |
|
543 </rm:data> |
|
544 <rm:data field="name" size="varies" type="string<>"> |
|
545 the union name |
|
546 </rm:data> |
|
547 <rm:data field="disc_type" size="varies" type="TYPEREF"> |
|
548 the discriminant type |
|
549 </rm:data> |
|
550 <rm:data field="hasdefault" size="4" type="boolean"> |
|
551 false |
|
552 </rm:data> |
|
553 <rm:data field="arms" size="varies" type="ARM-TYPE<>"> |
|
554 ordered list of arms |
|
555 </rm:data> |
|
556 </rm:proto> |
|
557 |
|
558 <rm:proto name="UNION-TYPE (with default arm)"> |
|
559 <rm:data field="type_code" size="4" type="TYPE-CODE"> |
|
560 <literal>TC-UNION</literal> |
|
561 </rm:data> |
|
562 <rm:data field="name" size="varies" type="string<>"> |
|
563 the union name |
|
564 </rm:data> |
|
565 <rm:data field="disc_type" size="varies" type="TYPEREF"> |
|
566 the discriminant type |
|
567 </rm:data> |
|
568 <rm:data field="hasdefault" size="4" type="boolean"> |
|
569 true |
|
570 </rm:data> |
|
571 <rm:data field="def_optional" size="4" type="boolean"> |
|
572 is the default arm value optional? |
|
573 </rm:data> |
|
574 <rm:data field="def_type" size="varies" type="TYPEREF"> |
|
575 the default arm type |
|
576 </rm:data> |
|
577 <rm:data field="arms" size="varies" type="ARM-TYPE<>"> |
|
578 ordered list of arms |
|
579 </rm:data> |
|
580 </rm:proto> |
|
581 |
|
582 <para> |
|
583 Lastly, an enum type definition consists of a name, an optional |
|
584 fallback value, and a list of enumeration values. The value index |
|
585 referenced by <literal>ENUM-DATA</literal> is an index into the |
|
586 array of values defined by the corresponding |
|
587 <literal>ENUM-TYPE</literal>. |
|
588 </para> |
|
589 |
|
590 <rm:proto name="VALUE-TYPE"> |
|
591 <rm:data field="name" size="varies" type="string<>"> |
|
592 the value's name |
|
593 </rm:data> |
|
594 <rm:data field="value" size="4" type="int"> |
|
595 the value's assigned value |
|
596 </rm:data> |
|
597 </rm:proto> |
|
598 |
|
599 <rm:proto name="ENUM-TYPE"> |
|
600 <rm:data field="type_code" size="4" type="TYPE-CODE"> |
|
601 <literal>TC-ENUM</literal> |
|
602 </rm:data> |
|
603 <rm:data field="name" size="varies" type="string<>"> |
|
604 the enum name |
|
605 </rm:data> |
|
606 <rm:data field="fb_name" size="varies" type="string<> *"> |
|
607 the fallback value's name, if one exists |
|
608 </rm:data> |
|
609 <rm:data field="values" size="varies" type="VALUE-TYPE<>"> |
|
610 ordered list of values |
|
611 </rm:data> |
|
612 </rm:proto> |
|
613 |
|
614 <para> |
|
615 The type space itself is an array. Each element is one of these |
|
616 four type definitions (<literal>ARRAY-TYPE</literal>, |
|
617 <literal>STRUCT-TYPE</literal>, <literal>UNION-TYPE</literal>, or |
|
618 <literal>ENUM-TYPE</literal>). |
|
619 </para> |
|
620 |
|
621 <rm:proto name="TYPESPACE"> |
|
622 <rm:data field="types" size="varies" type="?-TYPE<>"> |
|
623 ordered list of types in the type space |
|
624 </rm:data> |
|
625 </rm:proto> |
|
626 |
|
627 </section> |
|
628 |
|
629 <section><title><acronym>API</acronym> definitions</title> |
|
630 <para> |
|
631 The ultimate description of the interactions permitted with a |
|
632 particular object is its <acronym>API</acronym> definition. An |
|
633 <acronym>API</acronym> definition contains many elements: an |
|
634 interface name, a list of versioned <acronym>API</acronym> names |
|
635 the <acronym>API</acronym> supports, and definitions of the |
|
636 <acronym>API</acronym>'s attributes, methods, and events. |
|
637 </para> |
|
638 |
|
639 <para> |
|
640 Each <acronym>API</acronym> name has a set of stabilities and |
|
641 versions: |
|
642 </para> |
|
643 |
|
644 <rm:proto name="STABILITY-CODE"> |
|
645 <rm:data field="stability_code" size="4" type="int"> |
|
646 <rm:codedef label="stability" prefix="sc"> |
|
647 <rm:code num="1" name="private" /> |
|
648 <rm:code num="2" name="uncommitted" /> |
|
649 <rm:code num="3" name="committed" /> |
|
650 </rm:codedef> |
|
651 </rm:data> |
|
652 </rm:proto> |
|
653 |
|
654 <rm:proto name="VERSION-DATA"> |
|
655 <rm:data field="stability" size="4" type="STABILITY-CODE"> |
|
656 stability version applies to |
|
657 </rm:data> |
|
658 <rm:data field="major" size="4" type="int"> |
|
659 major version number |
|
660 </rm:data> |
|
661 <rm:data field="minor" size="4" type="int"> |
|
662 minor version number |
|
663 </rm:data> |
|
664 </rm:proto> |
|
665 |
|
666 <rm:proto name="APINAME-DATA"> |
|
667 <rm:data field="api_name" size="varies" type="string<>"> |
|
668 API name |
|
669 </rm:data> |
|
670 <rm:data field="versions" size="varies" type="VERSION-DATA<>"> |
|
671 API versions by stability |
|
672 </rm:data> |
|
673 </rm:proto> |
|
674 |
|
675 <para> |
|
676 An attribute consists of a name, stability, various flags, a type, |
|
677 and separate, optional read and write error types. |
|
678 </para> |
|
679 |
|
680 <rm:proto name="ATTRIBUTE-TYPE"> |
|
681 <rm:data field="aname" size="varies" type="string<>"> |
|
682 attribute name |
|
683 </rm:data> |
|
684 <rm:data field="stability" size="4" type="STABILITY-CODE"> |
|
685 stability |
|
686 </rm:data> |
|
687 <rm:data field="readable" size="4" type="boolean"> |
|
688 is attribute readable? |
|
689 </rm:data> |
|
690 <rm:data field="writable" size="4" type="boolean"> |
|
691 is attribute writable? |
|
692 </rm:data> |
|
693 <rm:data field="optional" size="4" type="boolean"> |
|
694 is attribute optional? |
|
695 </rm:data> |
|
696 <rm:data field="type" size="varies" type="TYPEREF"> |
|
697 attribute type |
|
698 </rm:data> |
|
699 <rm:data field="read_error" size="varies" type="TYPEREF *"> |
|
700 error data on read, if applicable |
|
701 </rm:data> |
|
702 <rm:data field="write_error" size="varies" type="TYPEREF *"> |
|
703 error data on write, if applicable |
|
704 </rm:data> |
|
705 </rm:proto> |
|
706 |
|
707 <para> |
|
708 A method looks a lot like an attribute. It has a name, stability, |
|
709 a result type, only a single optional error type, and an array of |
|
710 argument definitions. |
|
711 </para> |
|
712 |
|
713 <rm:proto name="ARGUMENT-TYPE"> |
|
714 <rm:data field="argname" size="varies" type="string<>"> |
|
715 argument name |
|
716 </rm:data> |
|
717 <rm:data field="optional" size="4" type="boolean"> |
|
718 is argument optional? |
|
719 </rm:data> |
|
720 <rm:data field="type" size="varies" type="TYPEREF"> |
|
721 argument type |
|
722 </rm:data> |
|
723 </rm:proto> |
|
724 |
|
725 <rm:proto name="METHOD-TYPE"> |
|
726 <rm:data field="mname" size="varies" type="string<>"> |
|
727 method name |
|
728 </rm:data> |
|
729 <rm:data field="stability" size="4" type="STABILITY-CODE"> |
|
730 stability |
|
731 </rm:data> |
|
732 <rm:data field="optional" size="4" type="boolean"> |
|
733 is result optional? |
|
734 </rm:data> |
|
735 <rm:data field="result_type" size="varies" type="TYPEREF"> |
|
736 result type |
|
737 </rm:data> |
|
738 <rm:data field="error" size="varies" type="TYPEREF *"> |
|
739 error data, if applicable |
|
740 </rm:data> |
|
741 <rm:data field="args" size="varies" type="ARGUMENT-TYPE<>"> |
|
742 arguments |
|
743 </rm:data> |
|
744 </rm:proto> |
|
745 |
|
746 <para> |
|
747 An event consists only of a name, stability, and type. |
|
748 </para> |
|
749 |
|
750 <rm:proto name="EVENT-TYPE"> |
|
751 <rm:data field="ename" size="varies" type="string<>"> |
|
752 method name |
|
753 </rm:data> |
|
754 <rm:data field="stability" size="4" type="STABILITY-CODE"> |
|
755 stability |
|
756 </rm:data> |
|
757 <rm:data field="event_type" size="varies" type="TYPEREF"> |
|
758 event type |
|
759 </rm:data> |
|
760 </rm:proto> |
|
761 |
|
762 <para> |
|
763 Finally, an API definition combines all the above elements. |
|
764 </para> |
|
765 |
|
766 <rm:proto name="API-TYPE"> |
|
767 <rm:data field="ifname" size="varies" type="string<>"> |
|
768 interface name (domain) |
|
769 </rm:data> |
|
770 <rm:data field="apis" size="varies" type="APINAME-DATA<>"> |
|
771 API names and versions implemented |
|
772 </rm:data> |
|
773 <rm:data field="types" size="varies" type="TYPESET<>"> |
|
774 Types used by API definition |
|
775 </rm:data> |
|
776 <rm:data field="attributes" size="varies" type="ATTRIBUTE-TYPE<>"> |
|
777 API attributes |
|
778 </rm:data> |
|
779 <rm:data field="methods" size="varies" type="METHOD-TYPE<>"> |
|
780 API methods |
|
781 </rm:data> |
|
782 <rm:data field="events" size="varies" type="EVENT-TYPE<>"> |
|
783 API events |
|
784 </rm:data> |
|
785 </rm:proto> |
|
786 |
|
787 </section> |
|
788 |
|
789 </section> |
|
790 <section id="proto-handshake"><title>Connection Initialization</title> |
|
791 <para> |
|
792 Once a connection has been established between a client and server, |
|
793 a short synchronous handshake initiates the rad protocol. The |
|
794 server begins by sending a <literal>SERVER-HELLO</literal> |
|
795 message. This message specifies the minimum and maximum protocol |
|
796 versions (inclusive) recognized by the server. |
|
797 </para> |
|
798 |
|
799 <rm:proto name="SERVER-HELLO"> |
|
800 <rm:data field="protocol" size="3" type="string[3]"> |
|
801 <quote>RAD</quote> |
|
802 </rm:data> |
|
803 <rm:data field="min_ver" size="4" type="int"> |
|
804 minimum supported version |
|
805 </rm:data> |
|
806 <rm:data field="max_ver" size="4" type="int"> |
|
807 maximum supported version |
|
808 </rm:data> |
|
809 </rm:proto> |
|
810 |
|
811 <para> |
|
812 The client then replies with a <literal>CLIENT-HELLO</literal> |
|
813 message specifying the version it wishes to use. This version may |
|
814 not be less than the server's minimum version or greater than the |
|
815 server's maximum version. |
|
816 </para> |
|
817 |
|
818 <rm:proto name="CLIENT-HELLO"> |
|
819 <rm:data field="protocol" size="3" type="string[3]"> |
|
820 <quote>RAD</quote> |
|
821 </rm:data> |
|
822 <rm:data field="version" size="4" type="int"> |
|
823 client-selected version |
|
824 </rm:data> |
|
825 <rm:data field="locale" size="varies" type="string<256>"> |
|
826 client locale |
|
827 </rm:data> |
|
828 </rm:proto> |
|
829 |
|
830 <para> |
|
831 Part of the <literal>rad</literal> protocol is the communication of |
|
832 structured error data on request failures. For consistency with |
|
833 the object-specific errors that server-side objects are permitted |
|
834 to return, the errors returned by rad when requests fail for other |
|
835 reasons are also defined using <acronym>ADR</acronym>. After the |
|
836 server receives and accepts a <literal>CLIENT-HELLO</literal> |
|
837 message, it replies with <literal>ERRORS</literal> to communicate |
|
838 those type definitions: |
|
839 </para> |
|
840 |
|
841 <rm:proto name="ERRORS"> |
|
842 <rm:data field="error_space" size="varies" type="TYPESPACE"> |
|
843 typespace containing error types |
|
844 </rm:data> |
|
845 <rm:data field="errors" size="varies" type="TYPEREF<>"> |
|
846 errors types, starting with <literal>EC-NOMEM</literal> |
|
847 </rm:data> |
|
848 </rm:proto> |
|
849 |
|
850 <para> |
|
851 The <literal>TYPEREF</literal>s refer to the types defined in the |
|
852 <literal>error_space</literal> <literal>TYPESPACE</literal>. The |
|
853 types define the first <literal>error_count</literal> errors, |
|
854 starting from the first non object-specific error, |
|
855 <literal>EC-NOMEM</literal>. Any errors for which types are not |
|
856 defined have type <quote>void</quote>. |
|
857 </para> |
|
858 |
|
859 <!-- |
|
860 These errors are defined in ADR for convenience and for |
|
861 architectural consistency. However, from a interface perspective |
|
862 they should be part of the protocol and documented here. |
|
863 --> |
|
864 |
|
865 <para> |
|
866 At this point, the handshake is complete and normal client-server |
|
867 communication can occur. |
|
868 </para> |
|
869 </section> |
|
870 |
|
871 |
|
872 <section><title>Messages</title> |
|
873 <para> |
|
874 Normal communication consists of an asynchronous exchange of |
|
875 messages: <literal>REQUEST</literal>s from the client to the |
|
876 server, <literal>RESPONSE</literal>s from the server to the client, |
|
877 and <literal>EVENT</literal>s from the server to the client. |
|
878 </para> |
|
879 |
|
880 <para> |
|
881 A <literal>REQUEST</literal> is the <literal>rad</literal> |
|
882 equivalent of a low-level remote procedure call. It consists of a |
|
883 client-selected, non-zero serial number, an operation code, and an |
|
884 opaque, operation-specific, variable-length payload. |
|
885 </para> |
|
886 |
|
887 <rm:proto name="REQUEST"> |
|
888 <rm:data field="serial" size="8" type="hyper"> |
|
889 client-specified serial number |
|
890 </rm:data> |
|
891 <rm:data field="opcode" size="4" type="OP-CODE"> |
|
892 operation code (see <xref linkend="op-data-def" />) |
|
893 </rm:data> |
|
894 <rm:data field="payload" size="varies" type="opaque<>"> |
|
895 request payload |
|
896 </rm:data> |
|
897 </rm:proto> |
|
898 |
|
899 <para> |
|
900 The server will respond to every <literal>REQUEST</literal> with a |
|
901 <literal>RESPONSE</literal>. The structure of a |
|
902 <literal>RESPONSE</literal> varies depending on whether the server |
|
903 was successful in processing the client's request. A |
|
904 <literal>RESPONSE</literal> consists of the serial number of the |
|
905 corresponding <literal>REQUEST</literal>, a boolean indicating |
|
906 whether the request was successful, and either an |
|
907 operation-specific opaque payload (in the case of success), or an |
|
908 error code and an error-specific error payload (in the case of |
|
909 failure): |
|
910 </para> |
|
911 |
|
912 <rm:proto name="RESPONSE (successful)"> |
|
913 <rm:data field="serial" size="8" type="hyper"> |
|
914 serial number of REQUEST |
|
915 </rm:data> |
|
916 <rm:data field="success" size="4" type="boolean"> |
|
917 true |
|
918 </rm:data> |
|
919 <rm:data field="payload" size="varies" type="opaque<>"> |
|
920 response payload |
|
921 </rm:data> |
|
922 </rm:proto> |
|
923 |
|
924 <rm:proto name="RESPONSE (failure)"> |
|
925 <rm:data field="serial" size="8" type="hyper"> |
|
926 serial number of REQUEST |
|
927 </rm:data> |
|
928 <rm:data field="success" size="4" type="boolean"> |
|
929 false |
|
930 </rm:data> |
|
931 <rm:data field="error" size="4" type="ERROR-CODE"> |
|
932 error code (see <xref linkend="error-data-def" />) |
|
933 </rm:data> |
|
934 <rm:data field="payload" size="varies" type="opaque<>"> |
|
935 error payload |
|
936 </rm:data> |
|
937 </rm:proto> |
|
938 |
|
939 <para> |
|
940 The <literal>rad</literal> protocol doesn't require the client to |
|
941 wait for a <literal>RESPONSE</literal> before sending another |
|
942 <literal>REQUEST</literal>. However, the server implementation may |
|
943 place limits on the number of outstanding requests that can be |
|
944 handled simultaneously. A client with an outstanding |
|
945 <literal>REQUEST</literal> must assume that a subsequent |
|
946 <literal>REQUEST</literal> will block until the |
|
947 <literal>RESPONSE</literal> from the outstanding |
|
948 <literal>REQUEST</literal> is read. |
|
949 </para> |
|
950 |
|
951 <para> |
|
952 Lastly, a client may (via a <literal>REQUEST</literal>) subscribe |
|
953 to asynchronous event sources. When an event occurs, the server |
|
954 will send an <literal>EVENT</literal> message to the client. An |
|
955 <literal>EVENT</literal> message will include the object ID of the |
|
956 source object (more later), the time of the event, the name of the |
|
957 event, and an event-specific opaque payload. An |
|
958 <literal>EVENT</literal> message is distinguished from a |
|
959 <literal>RESPONSE</literal> by having a serial number of 0. |
|
960 </para> |
|
961 |
|
962 <rm:proto name="EVENT"> |
|
963 <rm:data field="serial" size="8" type="hyper"> |
|
964 0 |
|
965 </rm:data> |
|
966 <rm:data field="source" size="8" type="hyper"> |
|
967 id of generating object |
|
968 </rm:data> |
|
969 <rm:data field="sequence" size="8" type="hyper"> |
|
970 sequence number of event |
|
971 </rm:data> |
|
972 <rm:data field="timestamp" size="12" type="TIME-DATA"> |
|
973 time of event |
|
974 </rm:data> |
|
975 <rm:data field="name" size="varies" type="string<>"> |
|
976 event name |
|
977 </rm:data> |
|
978 <rm:data field="payload" size="varies" type="opaque<>"> |
|
979 event payload |
|
980 </rm:data> |
|
981 </rm:proto> |
|
982 |
|
983 </section> |
|
984 |
|
985 |
|
986 <section><title>Operations</title> |
|
987 <para> |
|
988 Each operation that a client can perform against a |
|
989 <command>rad</command> server has its own request and response |
|
990 payloads. To facilitate processing without needing to fully decode |
|
991 the payload, they are communicated as variable-lengthed |
|
992 <literal>opaque</literal> data in the <literal>REQUEST</literal> |
|
993 and <literal>RESPONSE</literal>. |
|
994 </para> |
|
995 |
|
996 <para> |
|
997 For consistency and flexibility, all <acronym>ADR</acronym> data |
|
998 referenced by these payloads is communicated as |
|
999 <literal>OPTIONAL-DATA</literal>, which in turn is wrapped as |
|
1000 <literal>opaque</literal> data. |
|
1001 </para> |
|
1002 |
|
1003 <rm:proto name="PAYLOAD-DATA"> |
|
1004 <rm:data field="data" size="varies" type="opaque<>"> |
|
1005 encapsulated <literal>OPTIONAL-DATA</literal> |
|
1006 </rm:data> |
|
1007 </rm:proto> |
|
1008 |
|
1009 <section><title>INVOKE</title> |
|
1010 |
|
1011 <para> |
|
1012 INVOKE makes a method call against a <command>rad</command> object, |
|
1013 identified by its object ID. |
|
1014 </para> |
|
1015 |
|
1016 <rm:proto name="INVOKE-REQUEST"> |
|
1017 <rm:data field="objectid" size="8" type="hyper"> |
|
1018 Object ID, returned by lookup |
|
1019 </rm:data> |
|
1020 <rm:data field="mname" size="varies" type="string<>"> |
|
1021 the method to invoke |
|
1022 </rm:data> |
|
1023 <rm:data field="arguments" size="varies" type="PAYLOAD-DATA<>"> |
|
1024 array of method arguments |
|
1025 </rm:data> |
|
1026 </rm:proto> |
|
1027 |
|
1028 <rm:proto name="INVOKE-RESPONSE"> |
|
1029 <rm:data field="result" size="varies" type="PAYLOAD-DATA"> |
|
1030 the return value of method call, if any |
|
1031 </rm:data> |
|
1032 </rm:proto> |
|
1033 |
|
1034 <rm:errors op="INVOKE"> |
|
1035 <rm:error code="EC-OBJECT"> |
|
1036 The method call was made but failed for an object-specific |
|
1037 reason. |
|
1038 </rm:error> |
|
1039 <rm:error code="EC-NOTFOUND"> |
|
1040 <literal>objectid</literal> isn't a known object id, or the |
|
1041 object doesn't have the method <literal>mname</literal>. |
|
1042 </rm:error> |
|
1043 <rm:error code="EC-MISMATCH"> |
|
1044 The wrong number of arguments were provided, or a |
|
1045 non-optional argument was missing. |
|
1046 </rm:error> |
|
1047 <rm:error code="EC-NOMEM"> |
|
1048 The server had insufficient resources to complete the |
|
1049 operation. |
|
1050 </rm:error> |
|
1051 <rm:error code="EC-SYSTEM"> |
|
1052 An unexpected internal error occurred. |
|
1053 </rm:error> |
|
1054 </rm:errors> |
|
1055 |
|
1056 </section> |
|
1057 |
|
1058 <section><title>GETATTR</title> |
|
1059 |
|
1060 <para> |
|
1061 GETATTR reads an attribute of a <command>rad</command> object, |
|
1062 identified by its object ID. |
|
1063 </para> |
|
1064 |
|
1065 <rm:proto name="GETATTR-REQUEST"> |
|
1066 <rm:data field="objectid" size="8" type="hyper"> |
|
1067 Object ID, returned by lookup |
|
1068 </rm:data> |
|
1069 <rm:data field="aname" size="varies" type="string<>"> |
|
1070 the attribute to read |
|
1071 </rm:data> |
|
1072 </rm:proto> |
|
1073 |
|
1074 <rm:proto name="GETATTR-RESPONSE"> |
|
1075 <rm:data field="result" size="varies" type="PAYLOAD-DATA"> |
|
1076 the value of the attribute |
|
1077 </rm:data> |
|
1078 </rm:proto> |
|
1079 |
|
1080 <rm:errors op="GETATTR"> |
|
1081 <rm:error code="EC-OBJECT"> |
|
1082 An attempt to read the attribute was made, but failed for |
|
1083 an object-specific reason. |
|
1084 </rm:error> |
|
1085 <rm:error code="EC-NOTFOUND"> |
|
1086 <literal>objectid</literal> isn't a known object id, or the |
|
1087 object doesn't have the attribute <literal>aname</literal>. |
|
1088 </rm:error> |
|
1089 <rm:error code="EC-ILLEGAL"> |
|
1090 <literal>aname</literal> refers to a write-only attribute. |
|
1091 </rm:error> |
|
1092 <rm:error code="EC-NOMEM"> |
|
1093 The server had insufficient resources to complete the |
|
1094 operation. |
|
1095 </rm:error> |
|
1096 <rm:error code="EC-SYSTEM"> |
|
1097 An unexpected internal error occurred. |
|
1098 </rm:error> |
|
1099 </rm:errors> |
|
1100 |
|
1101 </section> |
|
1102 |
|
1103 <section><title>SETATTR</title> |
|
1104 |
|
1105 <para> |
|
1106 SETATTR reads an attribute of a <command>rad</command> object, |
|
1107 identified by its object ID. The response payload for a SETATTR |
|
1108 request is empty. |
|
1109 </para> |
|
1110 |
|
1111 <rm:proto name="SETATTR-REQUEST"> |
|
1112 <rm:data field="objectid" size="8" type="hyper"> |
|
1113 Object ID, returned by lookup |
|
1114 </rm:data> |
|
1115 <rm:data field="aname" size="varies" type="string<>"> |
|
1116 the attribute to write |
|
1117 </rm:data> |
|
1118 <rm:data field="value" size="varies" type="PAYLOAD-DATA"> |
|
1119 the new value of the attribute |
|
1120 </rm:data> |
|
1121 </rm:proto> |
|
1122 |
|
1123 <rm:errors op="SETATTR"> |
|
1124 <rm:error code="EC-OBJECT"> |
|
1125 An attempt to write the attribute was made, but failed for |
|
1126 an object-specific reason. |
|
1127 </rm:error> |
|
1128 <rm:error code="EC-NOTFOUND"> |
|
1129 <literal>objectid</literal> isn't a known object id, or the |
|
1130 object doesn't have the attribute <literal>aname</literal>. |
|
1131 </rm:error> |
|
1132 <rm:error code="EC-MISMATCH"> |
|
1133 <literal>aname</literal> has a non-optional value and |
|
1134 <literal>value</literal> was NULL. |
|
1135 </rm:error> |
|
1136 <rm:error code="EC-ILLEGAL"> |
|
1137 <literal>aname</literal> refers to a read-only attribute. |
|
1138 </rm:error> |
|
1139 <rm:error code="EC-NOMEM"> |
|
1140 The server had insufficient resources to complete the |
|
1141 operation. |
|
1142 </rm:error> |
|
1143 <rm:error code="EC-SYSTEM"> |
|
1144 An unexpected internal error occurred. |
|
1145 </rm:error> |
|
1146 </rm:errors> |
|
1147 |
|
1148 </section> |
|
1149 |
|
1150 <section><title>LOOKUP</title> |
|
1151 |
|
1152 <para> |
|
1153 LOOKUP attempts to find the named object in the server's namespace, |
|
1154 returning the object and API IDs of the object if it exists. Since |
|
1155 an object isn't usable until its API has been DEFINEed, the client |
|
1156 may request the API definition be provided as part of the LOOKUP |
|
1157 response. For the same reason, the server may unilaterally decide |
|
1158 to provide the API definition if it believes the client hasn't seen |
|
1159 it yet. |
|
1160 </para> |
|
1161 |
|
1162 <rm:proto name="LOOKUP-REQUEST"> |
|
1163 <rm:data field="name" size="varies" type="NAME-DATA"> |
|
1164 object name |
|
1165 </rm:data> |
|
1166 <rm:data field="define" size="4" type="boolean"> |
|
1167 include object definition? |
|
1168 </rm:data> |
|
1169 </rm:proto> |
|
1170 |
|
1171 <rm:proto name="LOOKUP-RESPONSE"> |
|
1172 <rm:data field="objectid" size="8" type="hyper"> |
|
1173 ID of the object |
|
1174 </rm:data> |
|
1175 <rm:data field="apiid" size="8" type="hyper"> |
|
1176 ID of the object's API |
|
1177 </rm:data> |
|
1178 <rm:data field="definition" size="varies" type="API-TYPE *"> |
|
1179 the definition of the object's API |
|
1180 </rm:data> |
|
1181 </rm:proto> |
|
1182 |
|
1183 <rm:errors op="LOOKUP"> |
|
1184 <rm:error code="EC-NOTFOUND"> |
|
1185 <literal>name</literal> doesn't exist. |
|
1186 </rm:error> |
|
1187 <rm:error code="EC-NOMEM"> |
|
1188 The server had insufficient resources to complete the |
|
1189 operation. |
|
1190 </rm:error> |
|
1191 <rm:error code="EC-SYSTEM"> |
|
1192 An unexpected internal error occurred. |
|
1193 </rm:error> |
|
1194 </rm:errors> |
|
1195 |
|
1196 </section> |
|
1197 |
|
1198 <section><title>DEFINE</title> |
|
1199 |
|
1200 <para> |
|
1201 DEFINE requests a definition of the specified API ID. |
|
1202 </para> |
|
1203 |
|
1204 <rm:proto name="DEFINE-REQUEST"> |
|
1205 <rm:data field="apiid" size="8" type="hyper"> |
|
1206 API ID |
|
1207 </rm:data> |
|
1208 </rm:proto> |
|
1209 |
|
1210 <rm:proto name="DEFINE-RESPONSE"> |
|
1211 <rm:data field="definition" size="varies" type="API-TYPE"> |
|
1212 the definition of the API |
|
1213 </rm:data> |
|
1214 </rm:proto> |
|
1215 |
|
1216 <rm:errors op="DEFINE"> |
|
1217 <rm:error code="EC-NOTFOUND"> |
|
1218 <literal>apiid</literal> isn't a known |
|
1219 <acronym>API</acronym> ID. |
|
1220 </rm:error> |
|
1221 <rm:error code="EC-NOMEM"> |
|
1222 The server had insufficient resources to complete the |
|
1223 operation. |
|
1224 </rm:error> |
|
1225 <rm:error code="EC-SYSTEM"> |
|
1226 An unexpected internal error occurred. |
|
1227 </rm:error> |
|
1228 </rm:errors> |
|
1229 |
|
1230 </section> |
|
1231 |
|
1232 <section><title>LIST</title> |
|
1233 |
|
1234 <para> |
|
1235 LIST requests an enumeration of all objects present in the server |
|
1236 that match the specified object name pattern. The empty string |
|
1237 matches all server objects. |
|
1238 </para> |
|
1239 |
|
1240 <rm:proto name="LIST-REQUEST"> |
|
1241 <rm:data field="pattern" size="varies" type="NAME-DATA"> |
|
1242 object name pattern |
|
1243 </rm:data> |
|
1244 </rm:proto> |
|
1245 |
|
1246 <rm:proto name="LIST-RESPONSE"> |
|
1247 <rm:data field="names" size="varies" type="NAME-DATA<>"> |
|
1248 the definition of the API |
|
1249 </rm:data> |
|
1250 </rm:proto> |
|
1251 |
|
1252 <rm:errors op="LIST"> |
|
1253 <rm:error code="EC-NOMEM"> |
|
1254 The server had insufficient resources to complete the |
|
1255 operation. |
|
1256 </rm:error> |
|
1257 <rm:error code="EC-SYSTEM"> |
|
1258 An unexpected internal error occurred. |
|
1259 </rm:error> |
|
1260 </rm:errors> |
|
1261 |
|
1262 </section> |
|
1263 |
|
1264 <section><title>SUB and UNSUB</title> |
|
1265 |
|
1266 <para> |
|
1267 SUB and UNSUB subscribe and unsubscribe, respectively, to the named |
|
1268 event of the specified object. The response payload for a |
|
1269 successful SUB or UNSUB is empty. |
|
1270 </para> |
|
1271 |
|
1272 <para> |
|
1273 Note that it is possible to receive an <literal>EVENT</literal> |
|
1274 that has been UNSUBed after a successful UNSUB. |
|
1275 </para> |
|
1276 |
|
1277 <rm:proto name="SUB-REQUEST"> |
|
1278 <rm:data field="objectid" size="8" type="hyper"> |
|
1279 ID of the object |
|
1280 </rm:data> |
|
1281 <rm:data field="event" size="varies" type="string<>"> |
|
1282 event name |
|
1283 </rm:data> |
|
1284 </rm:proto> |
|
1285 |
|
1286 <rm:proto name="UNSUB-RESPONSE"> |
|
1287 <rm:data field="objectid" size="8" type="hyper"> |
|
1288 ID of the object |
|
1289 </rm:data> |
|
1290 <rm:data field="event" size="varies" type="string<>"> |
|
1291 event name |
|
1292 </rm:data> |
|
1293 </rm:proto> |
|
1294 |
|
1295 <rm:errors op="SUB"> |
|
1296 <rm:error code="EC-NOTFOUND"> |
|
1297 <literal>objectid</literal> isn't a known object id, or the |
|
1298 object doesn't have the event <literal>event</literal>. |
|
1299 </rm:error> |
|
1300 <rm:error code="EC-EXISTS"> |
|
1301 The client is already subscribed to <literal>event</literal>. |
|
1302 </rm:error> |
|
1303 <rm:error code="EC-NOMEM"> |
|
1304 The server had insufficient resources to complete the |
|
1305 operation. |
|
1306 </rm:error> |
|
1307 <rm:error code="EC-SYSTEM"> |
|
1308 An unexpected internal error occurred. |
|
1309 </rm:error> |
|
1310 </rm:errors> |
|
1311 |
|
1312 <rm:errors op="UNSUB"> |
|
1313 <rm:error code="EC-NOTFOUND"> |
|
1314 <literal>objectid</literal> isn't a known object id, the |
|
1315 object doesn't have the event <literal>event</literal>, or |
|
1316 the client isn't subscribed to <literal>event</literal>. |
|
1317 </rm:error> |
|
1318 <rm:error code="EC-NOMEM"> |
|
1319 The server had insufficient resources to complete the |
|
1320 operation. |
|
1321 </rm:error> |
|
1322 <rm:error code="EC-SYSTEM"> |
|
1323 An unexpected internal error occurred. |
|
1324 </rm:error> |
|
1325 </rm:errors> |
|
1326 |
|
1327 </section> |
|
1328 |
|
1329 </section> |
|
1330 |
|
1331 </appendix> |