summaryrefslogtreecommitdiff
path: root/spec/Connection_Interface_Contact_Info.xml
blob: 527d3252291484b42e6f85b38f01321024bdfd6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
<?xml version="1.0" ?>
<node name="/Connection_Interface_Contact_Info" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
  <tp:copyright> Copyright (C) 2008 Collabora Limited </tp:copyright>
  <tp:copyright> Copyright (C) 2008 Nokia Corporation </tp:copyright>
  <tp:license xmlns="http://www.w3.org/1999/xhtml">
    <p>This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.</p>

<p>This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.</p>

<p>You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
  </tp:license>
  <interface name="org.freedesktop.Telepathy.Connection.Interface.ContactInfo">
    <tp:added version="0.19.4">(as stable API)</tp:added>
    <tp:requires interface="org.freedesktop.Telepathy.Connection"/>

    <tp:struct name="Contact_Info_Field" array-name="Contact_Info_Field_List">
      <tp:member type="s" name="Field_Name">
        <tp:docstring>
          The name of the field; this is the lowercased name of a vCard field.
          For example, a field representing a contact's address would be named
          "adr".
        </tp:docstring>
      </tp:member>
      <tp:member type="as" name="Parameters">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>A list of vCard type parameters applicable to this field, with their
            values. The type parameter names, and any values that are
            case-insensitive in vCard, MUST be in lower case. For example, a
            contact's preferred home address would have parameters
            'type=home' and 'type=pref'.</p>

          <tp:rationale>
            The type parameter 'type' is likely to be the most common, but
            there can be others, such as 'language=en'.
          </tp:rationale>

          <p>Characters which are required to be escaped in vCard type
            parameters should not be escaped in this list. For instance,
            a field "X-FOO;SEMICOLON=\;:bar" in a vCard would become
            ('x-foo', ['semicolon=;'], ['bar']) in this interface.</p>

          <tp:rationale>
            This avoids Telepathy UIs having to understand the escaping and
            unescaping rules for vCards. The type parameter name is not
            allowed (by RFC 2425) to contain an '=' character, so no ambiguity
            is introduced.
          </tp:rationale>
        </tp:docstring>
      </tp:member>
      <tp:member type="as" name="Field_Value">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>For unstructured vCard fields (such as 'fn', a formatted name
            field), a single-element array containing the field's value.</p>

          <p>For structured fields (such as 'adr', an address field), an array
            corresponding to the semicolon-separated elements of the field (with
            empty strings for empty elements).</p>

          <p>A vCard field with multiple comma-separated values, such as
            'nickname', should be represented by several
            <tp:type>Contact_Info_Field</tp:type>s.</p>

          <p>Characters which are required to be escaped in vCard values, such as
            semi-colons and newlines, should not be escaped in this list (e.g. if
            a value contains a newline, the data passed over D-Bus should
            contain a literal newline character).</p>

          <tp:rationale>
            An earlier draft of this interface split structured vCard fields
            into multiple Telepathy-level fields; for example, 'n' became
            'family-name', 'given-name', etc.  But under this representation,
            omitting empty components leads to difficulty identifying where one
            name ends and another begins.  Consider the fields ['given-name',
            'honorific-suffixes', 'family-name', 'honorific-prefixes']: does
            this represent two 'n' fields, or one with incorrect component
            ordering?
          </tp:rationale>
        </tp:docstring>
      </tp:member>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Represents one piece of information about a contact, as modelled by
          a single vCard field. Of the fields defined in RFC 2426, common
          examples include:</p>

        <dl>
          <dt>fn</dt>
          <dd>The contact's full name, formatted to their liking</dd>

          <dt>n</dt>
          <dd>The contact's full name, divided into five parts: family name,
            given name, additional names, honorific prefixes, and honorific
            suffixes</dd>

          <dt>org</dt>
          <dd>The contact's organisation, divided into the organization's name
            possibly followed by one or more organizational unit names.</dd>

          <dt>adr</dt>
          <dd>A street address for the contact, divided into seven components:
            post office box, extended address, street address, locality (e.g.,
            city), region (e.g., state or province), the postal code, and the
            country name.</dd>

          <dt>label</dt>
          <dd>A free-form street address for the contact, formatted as a
            single value (with embedded newlines where necessary) suitable for
            printing on an address label</dd>

          <dt>tel</dt>
          <dd>A telephone number for the contact.</dd>

          <dt>email</dt>
          <dd>An email address for the contact.</dd>
        </dl>

        <p>For example, the following vCard:</p>

        <pre>
   BEGIN:vCard
   VERSION:3.0
   FN:Wee Ninja
   N;LANGUAGE=ja:Ninja;Wee;;;-san
   ORG:Collabora, Ltd.;Management Division;Human Resources\; Company Policy Enforcement
   ADR;TYPE=WORK,POSTAL,PARCEL:;;11 Kings Parade;Cambridge;Cambridgeshire
    ;CB2 1SJ;UK
   LABEL;TYPE=WORK,POSTAL,PARCEL:11 Kings Parade\nCambridge\nCambridgeshire\nUK\nCB2 1SJ
   TEL;TYPE=VOICE,WORK:+44 1223 362967, +44 7700 900753
   EMAIL;TYPE=INTERNET,PREF:wee.ninja@collabora.co.uk
   EMAIL;TYPE=INTERNET:wee.ninja@example.com
   URL:http://www.thinkgeek.com/geektoys/plush/8823/
   NICKNAME:HR Ninja,Enforcement Ninja
   END:vCard</pre>

        <p>would be represented by (in Python-like syntax):</p>

        <pre>
[
  ('fn', [], ['Wee Ninja']),
  ('n', ['language=ja'], ['Ninja', 'Wee', '', '', '-san']),
  ('org', [], ['Collabora, Ltd.', 'Management Division',
    'Human Resources; Company Policy Enforcement']),
  ('adr', ['type=work','type=postal','type=parcel'],
   ['','','11 Kings Parade','Cambridge', 'Cambridgeshire','CB2 1SJ','UK']),
  ('label', ['type=work','type=postal','type=parcel'],
   ['''11 Kings Parade
  Cambridge
  Cambridgeshire
  UK
  CB2 1SJ''']),
  ('tel', ['type=voice','type=work'], ['+44 1223 362967']),
  ('tel', ['type=voice','type=work'], ['+44 7700 900753']),
  ('email', ['type=internet','type=pref'], ['wee.ninja@collabora.co.uk']),
  ('email', ['type=internet'], ['wee.ninja@example.com']),
  ('url', [], ['http://www.thinkgeek.com/geektoys/plush/8823/']),
  ('nickname', [], ['HR Ninja']),
  ('nickname', [], ['Enforcement Ninja'])
]</pre>
      </tp:docstring>
    </tp:struct>

    <tp:mapping name="Contact_Info_Map" array-name="">
      <tp:docstring>A dictionary whose keys are contact handles and whose
        values are contact information..</tp:docstring>
      <tp:member type="u" tp:type="Contact_Handle" name="Handle"/>
      <tp:member type="a(sasas)" tp:type="Contact_Info_Field[]"
        name="Contact_Info"/>
    </tp:mapping>

    <signal name="ContactInfoChanged" tp:name-for-bindings="Contact_Info_Changed">
      <arg name="Contact" type="u" tp:type="Contact_Handle">
        <tp:docstring>
          An integer handle for the contact whose info has changed.
        </tp:docstring>
      </arg>
      <arg name="ContactInfo" type="a(sasas)" tp:type="Contact_Info_Field[]">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          An array of fields representing information about this contact.
        </tp:docstring>
      </arg>
      <tp:docstring>
        Emitted when a contact's information has changed or been received for
        the first time on this connection.
      </tp:docstring>
    </signal>

    <method name="GetContactInfo"
      tp:name-for-bindings="Get_Contact_Info">
      <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
        <tp:docstring>
          An array of handles representing contacts.
        </tp:docstring>
      </arg>
      <arg direction="out" name="ContactInfo" type="a{ua(sasas)}"
        tp:type="Contact_Info_Map">
        <tp:docstring>
          A dictionary mapping contact handles to information, whose keys are
          the subset of the requested list of handles for which information was
          cached.
        </tp:docstring>
      </arg>
      <tp:docstring>
        Request information on several contacts at once.  This SHOULD only
        return cached information, omitting handles for which no information is
        cached from the returned map.
      </tp:docstring>
    </method>

    <method name="RefreshContactInfo"
      tp:name-for-bindings="Refresh_Contact_Info">
      <arg direction="in" name="Contacts" type="au" tp:type="Contact_Handle[]">
        <tp:docstring>
          Integer handles for contacts.
        </tp:docstring>
      </arg>
      <tp:docstring>
        Retrieve information for the given contact, requesting it from the
        network if an up-to-date version is not cached locally. This method
        SHOULD return immediately, emitting
        <tp:member-ref>ContactInfoChanged</tp:member-ref> when the contacts'
        updated contact information is returned.

        <tp:rationale>
          This method allows a client with cached contact information to
          update its cache after a number of days.
        </tp:rationale>
      </tp:docstring>
      <tp:possible-errors>
        <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
        <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
      </tp:possible-errors>
    </method>

    <method name="RequestContactInfo"
      tp:name-for-bindings="Request_Contact_Info">
      <arg direction="in" name="Contact" type="u" tp:type="Contact_Handle">
        <tp:docstring>
          An integer handle for a contact.
        </tp:docstring>
      </arg>
      <arg direction="out" name="Contact_Info" type="a(sasas)"
        tp:type="Contact_Info_Field[]">
        <tp:docstring>
          Information about that contact.
        </tp:docstring>
      </arg>
      <tp:docstring>
        Retrieve information for a contact, requesting it from the network if
        it is not cached locally.

        <tp:rationale>
          This method is appropriate for an explicit user request to show
          a contact's information; it allows a UI to wait for the contact
          info to be returned.
        </tp:rationale>
      </tp:docstring>
      <tp:possible-errors>
        <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
        <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
        <tp:error name="org.freedesktop.Telepathy.Error.InvalidHandle"/>
        <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable">
          <tp:docstring>
            The contact's information could not be retrieved.
          </tp:docstring>
        </tp:error>
      </tp:possible-errors>
    </method>

    <method name="SetContactInfo" tp:name-for-bindings="Set_Contact_Info">
      <tp:docstring>
        Set new contact information for this connection, replacing existing
        information.  This method is only suppported if
        <tp:member-ref>ContactInfoFlags</tp:member-ref> contains
        <code>Can_Set</code>, and may only be passed fields conforming to
        <tp:member-ref>SupportedFields</tp:member-ref>.
      </tp:docstring>
      <arg direction="in" name="ContactInfo" type="a(sasas)"
        tp:type="Contact_Info_Field[]">
        <tp:docstring>
          The new information to be set.
        </tp:docstring>
      </arg>
      <tp:possible-errors>
        <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
        <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
        <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
        <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
        <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
          <tp:docstring>
            Setting your own information is not supported on this protocol.
          </tp:docstring>
        </tp:error>
        <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
          <tp:docstring>
            The supplied fields do not match the restrictions specified by
            <tp:member-ref>SupportedFields</tp:member-ref>.
          </tp:docstring>
        </tp:error>
      </tp:possible-errors>
    </method>

    <tp:flags name="Contact_Info_Flags" value-prefix="Contact_Info_Flag"
      type="u">
      <tp:docstring>
        Flags defining the behaviour of contact information on this protocol.
        Some protocols provide no information on contacts without an explicit
        request; others always push information to the connection manager as
        and when it changes.
      </tp:docstring>

      <tp:flag suffix="Can_Set" value="1">
        <tp:docstring>
          Indicates that <tp:member-ref>SetContactInfo</tp:member-ref> is
          supported on this connection.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Push" value="2">
        <tp:docstring>
          Indicates that the protocol pushes all contacts' information to the
          connection manager without prompting. If set,
          <tp:member-ref>ContactInfoChanged</tp:member-ref> will be emitted
          whenever contacts' information changes.
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <tp:simple-type name="VCard_Field" type="s">
      <tp:docstring>
        A string naming a field in a vCard, such as "fn" or "adr". Although
        these are case-insensitive in RFC 2425, in Telepathy they MUST be
        normalized to lower case. In the terminology of RFC 2425 this is
        called a "type name", and corresponds to the "name" production given
        in the ABNF.
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type name="VCard_Type_Parameter" type="s"
      array-name="VCard_Type_Parameter_List">
      <tp:docstring>
        A type parameter as defined by RFC 2426, such as "type=cell" or
        "language=en".
      </tp:docstring>
    </tp:simple-type>

    <property name="ContactInfoFlags" type="u" access="read"
      tp:type="Contact_Info_Flags" tp:name-for-bindings="Contact_Info_Flags">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>An integer representing the bitwise-OR of flags on this
          connection.</p>

        <p>This property MAY change, without change notification, at any time
          before the connection moves to status Connection_Status_Connected.
          It MUST NOT change after that point.</p>

        <tp:rationale>
          <p>Some XMPP servers, like Facebook Chat, do not allow the vCard to
            be changed (and so would not have the Can_Set flag). Whether the
            user's server is one of these cannot necessarily be detected until
            quite late in the connection process.</p>
        </tp:rationale>

      </tp:docstring>
    </property>

    <tp:struct name="Field_Spec" array-name="Field_Specs">
      <tp:docstring>A struct describing a vCard field, with parameters, that
        may be passed to <tp:member-ref>SetContactInfo</tp:member-ref> on this
        Connection.</tp:docstring>

      <tp:member type="s" name="Name" tp:type="VCard_Field">
        <tp:docstring>A vCard field name, such as 'tel'.</tp:docstring>
      </tp:member>

      <tp:member type="as" name="Parameters" tp:type="VCard_Type_Parameter[]">
        <tp:docstring>The set of vCard type parameters which may be set on this
          field. If this list is empty and the
          Contact_Info_Field_Flag_Parameters_Exact flag is not set, any vCard type
          parameters may be used.</tp:docstring>
      </tp:member>

      <tp:member type="u" name="Flags" tp:type="Contact_Info_Field_Flags">
        <tp:docstring>Flags describing the behaviour of this
          field.</tp:docstring>
      </tp:member>

      <tp:member type="u" name="Max">
        <tp:docstring>Maximum number of instances of this field which may be
          set.  MAXUINT32 is used to indicate that there is no
          limit.</tp:docstring>
      </tp:member>
    </tp:struct>

    <property name="SupportedFields" type="a(sasuu)" tp:type="Field_Spec[]"
      access="read" tp:name-for-bindings="Supported_Fields">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of field specifications describing the kinds of fields which may
          be passed to <tp:member-ref>SetContactInfo</tp:member-ref>.  The empty
          list indicates that arbitrary vCard fields are permitted.  This
          property SHOULD be the empty list, and be ignored by clients, if
          <tp:member-ref>ContactInfoFlags</tp:member-ref> does not contain the
          Can_Set flag.</p>

        <p>For example, a protocol in which arbitrary vCards were stored
          as-is would set this property to the
          empty list. A protocol whose notion of contact information is one
          each of personal phone number, mobile phone number, location, email
          address and date of birth, with no attributes allowed on each piece
          of information, would set this property to (in Python-like
          syntax):</p>

        <pre>
[
  ('tel', ['type=home'], Parameters_Exact, 1),
  ('tel', ['type=cell'], Parameters_Exact, 1),
  ('adr', [], Parameters_Exact, 1),
  ('bday', [], Parameters_Exact, 1),
  ('email', ['type=internet'], Parameters_Exact, 1),
]</pre>

        <p>A protocol which allows users to specify up to four phone numbers,
          which may be labelled as personal and/or mobile, would set this
          property to
          <code>[ ('tel', ['type=home', 'type=cell'], 0, 4), ]</code>.</p>

        <tp:rationale>
          <p>Studying existing IM protocols shows that in practice protocols
            allow either a very restricted set of fields (such as MSN, which
            seems to correspond roughly to the largest example above), or
            something mapping 1:1 to a large subset of vCard (such as XMPP's
            XEP-0054).</p>
        </tp:rationale>

        <p>This property MAY change, without change notification, at any time
          before the connection moves to status Connection_Status_Connected.
          It MUST NOT change after that point.</p>

        <tp:rationale>
          <p>Some XMPP servers, like Google Talk, only allow a small subset of
            the "vcard-temp" protocol. Whether the user's server is one of
            these cannot be detected until quite late in the connection
            process.</p>
        </tp:rationale>
      </tp:docstring>
    </property>

    <tp:flags name="Contact_Info_Field_Flags"
      value-prefix="Contact_Info_Field_Flag" type="u">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        Flags describing the behaviour of a vCard field.
      </tp:docstring>
      <tp:flag suffix="Parameters_Exact" value="1">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>If present, exactly the parameters indicated must be set on this
            field; in the case of an empty list of parameters, this implies that
            parameters may not be used.</p>

          <p>If absent, and the list of allowed parameters is non-empty,
            any (possibly empty) subset of that list may be
            used.</p>

          <p>If absent, and the list of allowed parameters is empty,
            any parameters may be used.</p>
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Overwritten_By_Nickname" value="2">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Indicates that this field will be overwritten when the user's alias
            is changed with <tp:dbus-ref
              namespace="ofdT.Connection.Interface.Aliasing">SetAliases</tp:dbus-ref>
            or when the Account's <tp:dbus-ref
              namespace="ofdT.Account">Nickname</tp:dbus-ref>
            is updated.  Clients that allow the editing of the Alias and the
            ContactInfo in the same location should hide fields with this flag.</p>
          <tp:rationale>
            <p>If a client allowed the user to edit both the nickname and the
              ContactInfo field at the same time, the user could set them to two
              different values even though they map to the same property.  This
              would result in surprising behavior where the second value would
              win over the first.</p>
          </tp:rationale>
          <p>In addition to hiding this field when editing ContactInfo together
            with the user's nickname, it is recommended that clients call
            <tp:member-ref>SetContactInfo</tp:member-ref> before setting the
            user's nickname.</p>
          <tp:rationale>
            <p>This ensures that if the user changes the nickname, the correct
              value will get set even if the stale nickname is mistakenly sent
              along with <tp:member-ref>SetContactInfo</tp:member-ref>.</p>
          </tp:rationale>
          <p>If used, this flag typically appears on either the 'nickname' or
            'fn' field.</p>
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
      <p>An interface for requesting information about a contact on a given
        connection. Information is represented as a list of
        <tp:type>Contact_Info_Field</tp:type>s forming a
        structured representation of a vCard (as defined by RFC 2426), using
        field names and semantics defined therein.</p>

      <p>On some protocols, information about your contacts is pushed to you,
        with change notification; on others, like XMPP, the client must
        explicitly request the avatar, and has no way to tell whether it has
        changed without retrieving it in its entirety. This distinction is
        exposed by <tp:member-ref>ContactInfoFlags</tp:member-ref> containing
        the Push flag.</p>

      <p>On protocols with the Push flag set, UIs can connect to
        <tp:member-ref>ContactInfoChanged</tp:member-ref>, call
        <tp:member-ref>GetContactInfo</tp:member-ref> once at login for the set
        of contacts they are interested in, and then be sure they will receive
        the latest contact info. On protocols like XMPP, clients can do the
        same, but will receive (at most) opportunistic updates if the info is
        retrieved for other reasons. Clients may call
        <tp:member-ref>RequestContactInfo</tp:member-ref> or
        <tp:member-ref>RefreshContactInfo</tp:member-ref> to force a contact's
        info to be updated, but MUST NOT do so unless this is either in
        response to direct user action, or to refresh their own cache after a
        number of days.</p>

      <tp:rationale>
        <p>We don't want clients to accidentally cause a ridiculous amount of
          network traffic.</p>
      </tp:rationale>
    </tp:docstring>

    <tp:contact-attribute name="info"
      type="a(sasas)" tp:type="Contact_Info_Field[]">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>The same value that would be returned by
          <tp:member-ref>GetContactInfo</tp:member-ref> for this contact.
          Omitted from the result if the contact's info
          is not known.</p>
      </tp:docstring>
    </tp:contact-attribute>

  </interface>
</node>
<!-- vim:set sw=2 sts=2 et ft=xml: -->