summaryrefslogtreecommitdiff
path: root/spec/Channel_Interface_Messages.xml
blob: a88576dc8fad81cc20c3c738cc851949389d41db (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
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
<?xml version="1.0" ?>
<node name="/Channel_Interface_Messages"
  xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
  <tp:copyright>Copyright © 2008–2010 Collabora Ltd.</tp:copyright>
  <tp:copyright>Copyright © 2008–2010 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.Channel.Interface.Messages">
    <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.Text"/>
    <tp:added version="0.17.16">(as stable API)</tp:added>

    <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
      <p>This interface extends the <tp:dbus-ref
          namespace='org.freedesktop.Telepathy.Channel.Type'>Text</tp:dbus-ref>
        interface to support more general messages, including:</p>

      <ul>
        <li>messages with attachments (like MIME multipart/mixed)</li>
        <li>groups of alternatives (like MIME multipart/alternative)</li>
        <li>delivery reports (which replace <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type">Text.SendError</tp:dbus-ref>),
          addding support for protocols where the message content is not echoed
          back to the sender on failure and for receiving positive
          acknowledgements, as well as ensuring that incoming delivery reports
          are not lost if no client is handling the channel yet;</li>
        <li>any extra types of message we need in future</li>
      </ul>

      <p>Incoming messages, outgoing messages, and delivery reports are all
        represented as lists of <tp:type>Message_Part</tp:type> structures,
        with a format reminiscent of e-mail. Messages are sent by calling
        <tp:member-ref>SendMessage</tp:member-ref>; outgoing messages are
        announced to other clients which may be interested in the channel by
        the <tp:member-ref>MessageSent</tp:member-ref> signal. Incoming
        messages and delivery reports are signalled by
        <tp:member-ref>MessageReceived</tp:member-ref>, and are stored in the
        the <tp:member-ref>PendingMessages</tp:member-ref> property until
        acknowledged by calling <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type">Text.AcknowledgePendingMessages</tp:dbus-ref>.
        Only the <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
        for a channel should acknowledge messages; <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Client">Observer</tp:dbus-ref>s
        (such as loggers) and <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Client">Approver</tp:dbus-ref>s
        for the channel may listen for incoming messages, and send messages of their own, but SHOULD NOT acknowledge messages.</p>

      <tp:rationale>
        <p>If observers were allowed to acknowledge messages, then messages
          might have been acknowledged before the handler even got to see the
          channel, and hence could not be shown to the user.</p>
      </tp:rationale>

      <p>If this interface is present, clients that support it SHOULD
        listen for the <tp:member-ref>MessageSent</tp:member-ref> and
        <tp:member-ref>MessageReceived</tp:member-ref> signals, and
        ignore the <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type.Text">Sent</tp:dbus-ref>,
        <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type.Text">SendError</tp:dbus-ref>
        and <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type.Text">Received</tp:dbus-ref>
        signals on the Text interface (which are guaranteed to duplicate
        signals from this interface).</p>

      <p>Although this specification supports formatted (rich-text)
        messages with unformatted alternatives, implementations SHOULD NOT
        attempt to send formatted messages until the Telepathy specification
        has also been extended to cover capability discovery for message
        formatting.</p>

      <tp:rationale>
        We intend to expose all rich-text messages as XHTML-IM, but on some
        protocols, formatting is an extremely limited subset of that format
        (e.g. there are protocols where foreground/background colours, font
        and size can be set, but only for entire messages).
        Until we can tell UIs what controls to offer to the user, it's
        unfriendly to offer the user controls that may have no effect.
      </tp:rationale>
    </tp:docstring>

    <property name="SupportedContentTypes" type="as" access="read"
      tp:name-for-bindings="Supported_Content_Types"
      tp:immutable="yes">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of MIME types supported by this channel, with more preferred
          MIME types appearing earlier in the list. The list MAY include "*/*"
          to indicate that attachments with arbitrary MIME types can be sent.
          This list MUST NOT be empty, since all Messages implementations
          MUST accept messages containing a single "text/plain" part.</p>

        <p>Items in this list MUST be normalized to lower-case.</p>

        <p>Some examples of how this property interacts with the
          <tp:member-ref>MessagePartSupportFlags</tp:member-ref>:</p>

        <dl>
          <dt>A simple IM implementation: only plain text messages are
            allowed</dt>
          <dd>SupportedContentTypes = ['text/plain'],
            MessagePartSupportFlags = 0</dd>

          <dt>Formatted text with a plain text alternative is allowed (see the
            HTML interface draft)</dt>
          <dd>SupportedContentTypes = ['text/html', 'text/plain'],
            MessagePartSupportFlags = 0</dd>

          <dt>JPEG or PNG images may be sent, but without any attached
            text</dt>
          <dd>SupportedContentTypes = ['text/plain', 'image/jpeg',
            'image/png'], MessagePartSupportFlags = 0</dd>

          <dt>Unformatted text to which an optional JPEG or PNG image may be
            attached</dt>
          <dd>SupportedContentTypes = ['text/plain', 'image/jpeg',
            'image/png'], MessagePartSupportFlags = One_Attachment</dd>

          <dt>Formatted text to which arbitrarily many images may be
            attached</dt>
          <dd>SupportedContentTypes = ['text/html', 'text/plain', 'image/jpeg',
            'image/png', 'image/x-ms-bmp'], MessagePartSupportFlags =
            One_Attachment | Multiple_Attachments</dd>

          <dt>A full SIP implementation: arbitrary MIME messages are
            allowed</dt>
          <dd>SupportedContentTypes = ['*/*'], MessagePartSupportFlags =
            One_Attachment | Multiple_Attachments</dd>
        </dl>
      </tp:docstring>
    </property>

    <property name="MessageTypes" type="au"
      tp:type="Channel_Text_Message_Type[]" access="read"
      tp:name-for-bindings="Message_Types"
      tp:immutable="yes">
      <tp:added version="0.21.5">
        This supersedes <tp:dbus-ref namespace="ofdT.Channel.Type.Text"
          >GetMessageTypes</tp:dbus-ref>; fall back to that method for
        compatibility with older connection managers.
      </tp:added>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of message types which may be sent on this channel.</p>
      </tp:docstring>
    </property>

    <property name="MessagePartSupportFlags" type="u"
      tp:type="Message_Part_Support_Flags" access="read"
      tp:name-for-bindings="Message_Part_Support_Flags"
      tp:immutable="yes">
      <tp:docstring>
        Flags indicating the level of support for message parts on this
        channel.
      </tp:docstring>
    </property>

    <tp:flags name="Message_Part_Support_Flags"
      value-prefix="Message_Part_Support_Flag" type="u">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Flags indicating the level of support for message parts on this
          channel. They are designed such that setting more flags always
          implies that the channel has more capabilities.</p>

        <p>If no flags are set, this indicates that messages may contain
          a single message part whose content-type is any of the types
          from SupportedContentTypes, possibly with some alternatives.</p>

        <p>There is no flag indicating support for alternatives. This is
          because the SendMessage implementation can always accept messages
          containing alternatives, even if the underlying protocol does not,
          by deleting all alternatives except the first (most preferred)
          that is supported.</p>

        <tp:rationale>
          Each of the flags so far implies the previous flag, so we could
          have used a simple enumeration here; however, we've defined
          the message-part support indicator as a flag set for future
          expansion.
        </tp:rationale>

        <p>See <tp:member-ref>SupportedContentTypes</tp:member-ref> for some
          examples.</p>
      </tp:docstring>

      <tp:flag suffix="One_Attachment" value="1">
        <tp:docstring>
          <tp:member-ref>SendMessage</tp:member-ref> will accept messages
          containing a textual message body,
          plus a single attachment of any type listed in the
          SupportedContentTypes property. It does not make sense for this
          flag to be set if Message_Part_Support_Flag_Data_Only is not also set
          (because the connection manager can trivially provide an empty text
          part if necessary).
        </tp:docstring>
      </tp:flag>
      <tp:flag suffix="Multiple_Attachments" value="2">
        <tp:docstring>
          SendMessage will accept messages containing a textual message body,
          plus an arbitrary number of attachments of any type listed in the
          SupportedContentTypes property. It does not make sense for this
          flag to be set if Message_Part_Support_Flag_One_Attachment is not
          also set.
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <tp:mapping name="Message_Part" array-name="Message_Part_List"
      array-depth="2">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Part of a message's content. In practice, this mapping never
          appears in isolation: incoming messages are represented by a list of
          <tp:type>Message_Part</tp:type> mappings in the
          <tp:member-ref>MessageReceived</tp:member-ref> signal, and outgoing
          messages are passed to <tp:member-ref>SendMessage</tp:member-ref> as
          a list of these mappings.</p>

        <p>The first part of the message contains "headers", which refer
          to the entire message. The second and subsequent parts contain the
          message's content, including plain text, formatted text and/or
          attached files. Well-known keys for the header and body parts are
          defined by the <tp:type>Message_Header_Key</tp:type> and
          <tp:type>Message_Body_Key</tp:type> types, respectively.  It is an
          error for a connection manager to put keys referring to the message
          as a whole in the second or subsequent Message_Part, or keys intended
          for body parts in the first Message_Part; clients MUST recover from
          this error by ignoring these mis-placed keys.</p>

        <tp:rationale>
          <p>Instead of representing messages as aa{sv} where the first
            dictionary is special (a dictionary of headers), we could have
            used a signature like (a{sv}aa{sv}) to separate out the headers
            and the body parts.</p>

          <p>However, this would make access to the messages more awkward.
            In Python, the syntax for access to a header field would remain
            <code>message[0]['message-type']</code>, but access to a body
            field in the second body part would change from
            <code>message[2]['content'] to message[1][1]['content']</code>. In
            GLib, the message would change from being a
            <code>GPtrArray(GHashTable)</code> to being a
            <code>GValueArray(GHashTable, GPtrArray(GHashTable))</code> which
            is rather inconvenient to dereference.</p>
        </tp:rationale>

        <p>In any group of parts with the same non-empty value for the
          <tt>alternative</tt> key (which represent alternative versions of the
          same content), more faithful versions of the intended message MUST
          come before less faithful versions (note that this order is the
          opposite of MIME <tt>multipart/alternative</tt> parts). Clients
          SHOULD display the first alternative that they understand.</p>

        <tp:rationale>
          <p>Specifying the preference order means that if the underlying
            protocol doesn't support alternatives, the CM can safely delete
            everything apart from the first supported alternative when
            sending messages.</p>

          <p>The order is the reverse of MIME because MIME's rationale for
            placing the "plainest" part first (legibility in pre-MIME UAs)
            does not apply to us, and placing the most preferred part
            first simplifies display (a client can iterate the message
            in order, display the first alternative that it understands,
            and skip displaying all subsequent parts with the same
            "alternative" key).</p>
        </tp:rationale>

        <p>Clients SHOULD present all parts that are not redundant
          alternatives in the order they appear in this array, possibly
          excluding parts that are referenced by another displayed part.
          It is implementation-specific how the parts are presented to the
          user.</p>

        <tp:rationale>
          <p>This allows CMs to assume that all parts are actually shown to
            the user, even if they are not explicitly referenced - we do
            not yet recommend formatted text, and there is no way for
            plain text to reference an attachment since it has no concept of
            markup or references. This also forces clients to do something
            sensible with messages that consist entirely of "attachments",
            with no "body" at all.</p>

          <p>For instance, when displaying the above example, a client that
            understands the HTML part should display the JPEG image once,
            between the two lines "Here is a photo of my cat:" and
            "Isn't it cute?"; it may additionally present the image in some
            way for a second time, after "Isn't it cute?", or may choose
            not to.</p>

          <p>A client that does not understand HTML, displaying the same
            message, should display the plain-text part, followed by the JPEG
            image.</p>
        </tp:rationale>

        <p>Connection managers, clients and extensions to this specification
          SHOULD NOT include <tp:type>Handle</tp:type>s as values in a
          Message_Part, except for <code>message-sender</code> in the
          header.</p>

        <tp:rationale>
          <p>Reference-counting handles in clients becomes problematic if
            the channel proxy cannot know whether particular map values
            are handles or not.</p>
        </tp:rationale>

        <h4>Example messages</h4>

        <p>A rich-text message, with an embedded image, might be represented
          as:</p>

          <pre>
[
  {
    'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
    'message-sender': 42,
    'message-sent': 1210067943,
    'message-received': 1210067947,
    'message-type': 0,              # = Channel_Text_Message_Type_Normal
    'pending-message-id': 437,
  },
  { 'alternative': 'main',
    'content-type': 'text/html',
    'content': 'Here is a photo of my cat:&lt;br /&gt;' +
               '&lt;img src="cid:catphoto" alt="lol!" /&gt;' +
               '&lt;br /&gt;Isn't it cute?',
  },
  { 'alternative': 'main',
    'content-type': 'text/plain',
    'content': 'Here is a photo of my cat:\n[IMG: lol!]\nIsn't it cute?',
  },
  { 'identifier': 'catphoto',
    'content-type': 'image/jpeg',
    'size': 101000,
    'needs-retrieval': True,
  },
]</pre>

        <p>telepathy-ring, Nokia's GSM connection manager, represents vCards
          sent via SMS as:</p>

        <pre>
[
  {
    'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
    'message-sender': 42,
    'message-sent': 1210067943,
    'message-received': 1210067947,
    'message-type': 0,              # = Channel_Text_Message_Type_Normal
    'pending-message-id': 437,
  },
  { 'content-type': 'text/x-vcard',
    'content': [ 0x66, 0x69, 0x71, ...], # vCard data as an array of bytes
  },
]</pre>

        <h3>Delivery reports</h3>

        <div>
          <p>Delivery reports are also represented as messages with the
            <tt>message-type</tt> header mapping to
            <tp:type>Channel_Text_Message_Type</tp:type> Delivery_Report.
            Delivery reports SHOULD contain the <tt>message-sender</tt> header,
            mapping to the intended recipient of the original message, if
            possible; other headers specific to delivery reports are defined by
            the <tp:type>Delivery_Report_Header_Key</tp:type> type. The second
            and subsequent parts, if present, are a human-readable report from
            the IM service.</p>

          <p>For backwards- and forwards-compatibility, whenever a delivery
            error report is signalled—that is, with <tt>delivery-status</tt>
            mapping to <tp:type>Delivery_Status</tp:type> Temporarily_Failed or
            Permanently_Failed—<tp:dbus-ref
              namespace="org.freedesktop.Telepathy.Channel.Type.Text">SendError</tp:dbus-ref>
            SHOULD also be emitted; whenever <tp:dbus-ref
              namespace="org.freedesktop.Telepathy.Channel.Type.Text">SendError</tp:dbus-ref>
            is emitted, a delivery report MUST also be signalled.
            Delivery report messages on this interface MUST be represented in
            emissions of <tp:dbus-ref
              namespace="org.freedesktop.Telepathy.Channel.Type.Text">Received</tp:dbus-ref>
            as messages with the Non_Text_Content
            <tp:type>Channel_Text_Message_Flags</tp:type>; clients which
            understand this interface SHOULD ignore the SendError signal in
            favour of listening for delivery reports, as mentioned in the
            introduction.</p>

          <p>The result of attempting to send delivery reports using
            <tp:member-ref>SendMessage</tp:member-ref> is currently
            undefined.</p>

          <h4>Example delivery reports</h4>

          <dl>
            <dt>A minimal delivery report indicating permanent failure of the
              sent message whose token was
              <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code> for an unknown
              reason</dt>
            <dd><pre>
[{
# header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Permanently_Failed,
'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
}
# no body
]</pre></dd>

            <dt>A delivery report where the failed message is echoed back to the
              sender rather than being referenced by ID, and the failure reason
              is that this protocol cannot send messages to offline contacts
              such as the contact with handle 123</dt>
            <dd><pre>
[{ # header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Temporarily_Failed,
'delivery-error': Channel_Text_Send_Error_Offline,
'delivery-echo':
    [{ # header of original message
    'message-sender': 1,
    'message-sent': 1210067943,
    },
    { # body of original message
    'content-type': 'text/plain',
    'content': 'Hello, world!',
    }]
  ],

# no body
]</pre></dd>

            <dt>A maximally complex delivery report: the server reports a
              bilingual human-readable failure message because the user sent
              a message "Hello, world!" with token
              <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code> to a contact
              with handle 123, but that handle represents a contact who does not
              actually exist</dt>
            <dd><pre>
[{ # header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Permanently_Failed,
'delivery-error': Channel_Text_Send_Error_Invalid_Contact,
'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
'delivery-echo':
    [{ # header of original message
    'message-sender': 1,
    'message-sent': 1210067943,
    },
    { # body of original message
    'content-type': 'text/plain',
    'content': 'Hello, world!',
    }]
  ],
},
{ # message from server (alternative in English)
'alternative': '404',
'content-type': 'text/plain',
'lang': 'en',
'content': 'I have no contact with that name',
},
{ # message from server (alternative in German)
'alternative': '404'.
'content-type': 'text/plain',
'lang': 'de',
'content', 'Ich habe keinen Kontakt mit diesem Namen',
}
]</pre></dd>

            <dt>A minimal delivery report indicating successful delivery
              of the sent message whose token was
              <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code></dt>
            <dd><pre>
[{
# header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Delivered,
'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
}
# no body
]</pre></dd>

          </dl>

        </div>
      </tp:docstring>

      <tp:member name="Key" type="s">
        <tp:docstring>
          A key, which SHOULD be one of the well-known keys specified by
          <tp:type>Message_Header_Key</tp:type>,
          <tp:type>Message_Body_Key</tp:type> or
          <tp:type>Delivery_Report_Header_Key</tp:type> if possible.
        </tp:docstring>
      </tp:member>

      <tp:member name="Value" type="v">
        <tp:docstring>
          The value corresponding to the given key, which SHOULD be one of the
          specified types for well-known keys.
        </tp:docstring>
      </tp:member>
    </tp:mapping>

    <tp:simple-type type="s" name="Message_Header_Key">
      <tp:added version="0.19.8"/>
      <tp:changed version="0.21.5">
        Removed <tt>protocol-token</tt>—which had never been implemented—and
        respecified <tt>message-token</tt> not to have unimplementable
        uniqueness guarantees.
      </tp:changed>

      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Well-known keys for the first <tp:type>Message_Part</tp:type> of a
          message, which contains metadata about the message as a whole, along
          with the corresponding value types. Some keys make sense for both
          incoming and outgoing messages, while others are only meaningful for
          one or the other.</p>

          <dl>
            <dt>message-token (s -
              <tp:type>Protocol_Message_Token</tp:type>)
            </dt>
            <dd>
              <p>An opaque identifier for the message, as used by the
                underlying protocol. For outgoing messages, this SHOULD be
                globally unique; for incoming messages, this is <em>not</em>
                guaranteed to uniquely identify a message, <em>even within the
                scope of a single channel or contact</em>; the only guarantee
                made is that two messages with different <tt>message-token</tt>
                headers are different messages.</p>

              <p>Clients wishing to determine whether a new message with the
                <tt>scrollback</tt> header matches a previously-logged message
                with the same <tt>message-token</tt> SHOULD compare the
                message's sender, contents, <tt>message-sent</tt> or
                <tt>message-received</tt> timestamp, etc. Note that, in XMPP,
                the server only supplies a timestamp for scrollback messages,
                not for messages received while you are in a room; thus,
                non-scrollback messages will lack a <tt>message-sent</tt>
                timestamp.</p>

              <tp:rationale>
                <p>In practice, most protocols do not provide globally-unique
                  identifiers for messages. Connection managers, being
                  stateless, do not have the necessary information — namely, IM
                  logs — to generate reliable unique tokens for messages.</p>

                <p>For instance, some XMPP clients (including Gabble) stamp
                  messages they send with unique identifiers, but others number
                  outgoing messages in a conversation from 1 upwards.</p>
              </tp:rationale>
            </dd>

            <dt>message-sent (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The time the message was sent (if unavailable, the time
              it arrived at a central server MAY be used). Omitted if no
              reasonable approximation is available; SHOULD always be present
              on outgoing messages.</dd>

            <dt>message-received (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The time the message was received locally. SHOULD always
              be present.</dd>

            <dt>message-sender (u - <tp:type>Contact_Handle</tp:type>)</dt>
            <dd>The contact who sent the message. If 0 or omitted, the contact
              who sent the message could not be determined.</dd>

            <dt>message-sender-id (s)</dt>
            <dd>The identifier of the contact who sent the message,
              i.e. the result of calling <tp:dbus-ref
                namespace="ofdT.Connection">InspectHandles</tp:dbus-ref>
              on <code>message-sender</code>. If omitted, clients MUST
              fall back to looking at <code>message-sender</code>.</dd>

            <dt>sender-nickname (s)</dt>
            <dd>The nickname chosen by the sender of the message, which can be
              different for each message in a conversation.</dd>

            <dt>message-type (u - <tp:type>Channel_Text_Message_Type</tp:type>)
            </dt>
            <dd>The type of message; if omitted,
              Channel_Text_Message_Type_Normal MUST be assumed. MAY
              be omitted for normal chat messages.</dd>

            <dt>supersedes (s – <tp:type>Protocol_Message_Token</tp:type>)</dt>
            <dd>If present, this message supersedes a previous message,
              identified by its <tt>message-token</tt> header. The user
              interface MAY, for example, choose to replace the superseded
              message with this message, or grey out the superseded message.

              <tp:rationale>Skype, for example, allows the user to amend
                messages they have already sent (to correct typos,
                etc.).</tp:rationale>

              Connection Managers SHOULD represent repeatedly edited messages
              in the following form:
              <pre>
                message {token = a};
                message {token = b, supersedes = a};
                message {token = c, supersedes = a};
              </pre>

              <tp:rationale>The alternative form is:
                <pre>
                  message {token = a};
                  message {token = b, supersedes = a};
                  message {token = c, supersedes = b};
                </pre>
                but it is more difficult to implement in UIs/loggers, and it
                breaks irrecoverably if message b is lost. If a CM is forced
                to use this form, it should be tested extensively for
                interoperability with existing clients.
                </tp:rationale>

              Clients should deal gracefully if the original message gets
              lost, but one or more corrections to it get through:
              <pre>
                message {token = x} gets lost;
                message {token = y, supersedes = x};
                message {token = z, supersedes = x};
              </pre>

              <tp:rationale>This is the form that CMs will use to mean "I know
                that this message was edited, but I don't know what it
                originally said." It is often in the interests of the
                remote side for message x to be lost (e.g. to hide
                embarassing mistakes or sensitive information) so it might not
                be possible to retrieve it (even on protocols with reliable
                message-delivery guarantees).</tp:rationale></dd>

            <dt>original-message-sent (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The <tt>message-sent</tt> header of the message that this
              one supersedes.
              This key should only be present if <tt>supersedes</tt> is also
              present. It MAY be used as a hint to help clients locate the
              original message in its logs. If present, comparing the tuple
              (original-message-sent, supersedes) with (message-sent,
              message-token) SHOULD be enough to uniquely
              identify the original message.</dd>

            <dt>original-message-received (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The <tt>message-received</tt> header of the message that this
              one supersedes.
              This key should only be present if <tt>supersedes</tt> is also
              present. It MAY be used as a hint in a similar way to
              <tt>original-message-sent</tt>.</dd>

            <dt>pending-message-id (u - <tp:type>Message_ID</tp:type>)</dt>
            <dd>The incoming message ID. This MUST NOT be present on outgoing
              messages. Clients SHOULD NOT store this key - it is only valid
              for as long as the message remains unacknowledged.</dd>

            <dt>interface (s - <tp:type>DBus_Interface</tp:type>)</dt>
            <dd>This message is specific to the given interface, which is
              neither Text nor Messages. It SHOULD be ignored if that
              interface is not supported. (Note that an 'interface' key
              can also appear on the second and subsequent parts, where
              it indicates that that part (only) should be ignored if
              unsupported.)</dd>

            <dt>scrollback (b)</dt>
            <dd>If present and true, the incoming message was part of a
              replay of message history (this matches the Scrollback flag in
              <tp:type>Channel_Text_Message_Flags</tp:type>). This flag
              does not make sense on outgoing messages and SHOULD NOT
              appear there.</dd>

            <dt>rescued (b)</dt>
            <dd>If present and true, the incoming message has been seen in
              a previous channel during the lifetime of the Connection,
              but had not been acknowledged when that channel closed, causing
              an identical channel (in which the message now appears) to open.
              This matches the Rescued flag in
              <tp:type>Channel_Text_Message_Flags</tp:type>; it
              does not make sense on outgoing messages, and SHOULD NOT
              appear there.</dd>
          </dl>

      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type type="s" name="Message_Body_Key">
      <tp:added version="0.19.8"/>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Well-known keys for the second and subsequent
          <tp:type>Message_Part</tp:type>s of a message, which contain the
          message content, along with the corresponding value types.</p>

          <dl>
            <dt>identifier (s —
              <tp:type>Protocol_Content_Identifier</tp:type>)</dt>
            <dd>An opaque identifier for this part.
              Parts of a message MAY reference other parts by treating
              this identifier as if it were a MIME Content-ID and using
              the cid: URI scheme.</dd>

            <dt>alternative (s)</dt>
            <dd>
              <p>If present, this part of the message is an alternative for
                all other parts with the same value for "alternative".
                Clients SHOULD only display one of them (this is expected to
                be used for XHTML messages in a future version of this
                specification).</p>

              <p>If omitted, this part is not an alternative for any other
                part.</p>

              <p>Parts of a message MAY reference the group of alternatives
                as a whole (i.e. a reference to whichever of them is chosen)
                by treating this identifier as if it were the MIME Content-ID
                of a multipart/alternative part, and using the cid: URI
                scheme.</p>
            </dd>

            <dt>content-type (s)</dt>
            <dd>
              <p>The MIME type of this part. See the documentation
                for <tp:member-ref>MessageReceived</tp:member-ref> and
                <tp:member-ref>MessageSent</tp:member-ref> for notes on the
                special status of "text/plain" parts.</p>

              <p>Connection managers MUST NOT signal parts without a
                'content-type' key; if a protocol provides no way to determine
                the MIME type, the connection manager is responsible for
                guessing it, but MAY fall back to "text/plain" for text and
                "application/octet-stream" for non-text.</p>

              <p>Clients MUST ignore parts without a 'content-type' key, which
                are reserved for future expansion.</p>

              <p>When sending messages, clients SHOULD normalize the
                content-type to lower case, but connection managers SHOULD NOT
                rely on this. When signalling sent or received messages,
                connection managers MUST normalize the content-type to lower
                case.</p>
            </dd>

            <dt>lang (s)</dt>
            <dd>The natural language of this part, identified by a
              RFC 3066 language tag.

              <tp:rationale>
                XMPP allows alternative-selection by language as well as
                by content-type.
              </tp:rationale>
            </dd>

            <dt>size (u)</dt>
            <dd>The size in bytes (if needs-retrieval is true, this MAY be an
              estimated or approximate size). SHOULD be omitted if 'content'
              is provided.

              <tp:rationale>
                There's no point in providing the size if you're already
                providing all the content.
              </tp:rationale>
            </dd>

            <dt>thumbnail (b)</dt>
            <dd>
              <p>This part is a thumbnail. To represent an image together with
                its thumbnail in a single message, there should be one part for
                the full image followed by a part for the thumbnail (following
                the “more complete versions first” requirement), with the same
                'alternative' value. For example:</p>

              <pre>
[ ... ,
  { 'alternative': 'catphoto',
    'content-type': 'image/jpeg',
    'size': 150000,
    'content': [0xFF, 0xD8, ... 0xFF 0xD9],
  },
  { 'alternative': 'catphoto',
    'content-type': 'image/jpeg'
    'size': 1024,
    'thumbnail': True,
    'content': [0xFF, 0xD8, ... 0xFF 0xD9],
  },
  ...
]</pre>
            </dd>

            <dt>needs-retrieval (b)</dt>
            <dd>If false or omitted, the connection
              manager already holds this part in memory. If present and true,
              this part must be retrieved on demand (like MIME's
              <tt>message/external-body</tt>) by a mechanism to be defined later.

              <tp:rationale>The mechanism was meant to be
                <tp:member-ref>GetPendingMessageContent</tp:member-ref>, but
                that didn't work out. It's worth leaving the header in in
                preparation for a future mechanism.
              </tp:rationale>
            </dd>

            <dt>truncated (b)</dt>
            <dd>The content available via the 'content' key has been truncated
              by the server or connection manager (equivalent to
              Channel_Text_Message_Flag_Truncated in the Text interface).
            </dd>

            <dt>content (s or ay)</dt>
            <dd>The part's content, if it is available and
              sufficiently small to include here (implies that
              'needs-retrieval' is false or omitted). Otherwise, omitted.
              If the part is human-readable text or HTML, the value for this
              key MUST be a UTF-8 string (D-Bus signature 's').
              If the part is not text, the value MUST be a byte-array
              (D-Bus signature 'ay'). If the part is a text-based format
              that is not the main body of the message (e.g. an iCalendar
              or an attached XML document), the value SHOULD be a UTF-8 string,
              transcoding from another charset to UTF-8 if necessary, but
              MAY be a byte-array (of unspecified character set) if
              transcoding fails or the source charset is not known.</dd>

              <!-- FIXME: "sufficiently small to include" is not currently
              defined; we should add some API so clients can tell the
                CM how large a message it should emit in the signal.-->

            <dt>interface (s - <tp:type>DBus_Interface</tp:type>)</dt>
            <dd>This part is specific to the given interface, which is
              neither Text nor Messages. It SHOULD be ignored if that
              interface is not supported. (Note that an 'interface' key
              can also appear on the first part, where it indicates that the
              entire message should be ignored if unsupported.)</dd>
          </dl>
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type type="s" name="Delivery_Report_Header_Key">
      <tp:added version="0.19.8"/>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Well-known keys for the first <tp:type>Message_Part</tp:type> of a
          delivery report, along with the corresponding value types. Some of
          these are special-cases of headers defined by
          <tp:type>Message_Header_Key</tp:type>.</p>

          <dl>
            <dt>message-sender (u - <tp:type>Contact_Handle</tp:type>, as
              defined by <tp:type>Message_Header_Key</tp:type>)</dt>
            <dd>MUST be the intended recipient of the original message, if
              available (zero or omitted if the intended recipient is
              unavailable or is not a contact, e.g. a chatroom), even if the
              delivery report actually came from an intermediate server.</dd>

            <dt>message-type (u - <tp:type>Channel_Text_Message_Type</tp:type>,
              as defined by <tp:type>Message_Header_Key</tp:type>)</dt>
            <dd>MUST be Channel_Text_Message_Type_Delivery_Report.</dd>

            <dt>delivery-status (u - <tp:type>Delivery_Status</tp:type>)</dt>
            <dd>The status of the message. All delivery reports MUST contain
              this key in the first Message_Part.</dd>

            <dt>delivery-token (s - <tp:type>Protocol_Message_Token</tp:type>)</dt>

            <dd>
              <p>An identifier for the message to which this delivery report
                refers. MUST NOT be an empty string. Omitted if not
                available.</p>

              <p>Clients may match this against the token produced by the
                SendMessage method and MessageSent signal. A status report
                with no token could match any sent message, and a sent
                message with an empty token could match any status report.
                If multiple sent messages match, clients SHOULD use some
                reasonable heuristic.</p>

              <tp:rationale>
                In an ideal world, we could unambiguously match reports
                against messages; however, deployed protocols are not ideal,
                and not all reports and messages can be matched.
              </tp:rationale>
            </dd>

            <dt>delivery-error (u -
              <tp:type>Channel_Text_Send_Error</tp:type>)</dt>
            <dd>
              The reason for the failure. MUST be omitted if this was a
              successful delivery; SHOULD be omitted if it would be
              Channel_Text_Send_Error_Unknown.
            </dd>

            <dt>delivery-dbus-error (s -
              <tp:type>DBus_Error_Name</tp:type>)</dt>
            <dd>
              The reason for the failure, specified as a (possibly
              implementation-specific) D-Bus error. MUST be omitted if this was
              a successful delivery. If set, the 'delivery-error' key SHOULD be
              set to the closest available value.
            </dd>

            <dt>delivery-error-message (s)</dt>
            <dd>
              Debugging information on why the message could not be delivered.
              MUST be omitted if this was a successful delivery; MAY always be
              omitted.
            </dd>

            <dt>delivery-echo (aa{sv} - <tp:type>Message_Part[]</tp:type>)</dt>
            <dd>
              <p>The message content, as defined by the Messages interface.
                Omitted if no content is available. Content MAY have been
                truncated, message parts MAY have been removed, and message
                parts MAY have had their content removed (i.e. the message part
                metadata is present, but the 'content' key is not).</p>

              <tp:rationale>
                Some protocols, like XMPP, echo the failing message back to
                the sender. This is sometimes the only way to match it
                against the sent message, so we include it here.
              </tp:rationale>
            </dd>

          </dl>
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type type="u" name="Message_Part_Index"
      array-name="Message_Part_Index_List">
      <tp:deprecated version="0.21.5">
        This type is only used by
        <tp:member-ref>GetPendingMessageContent</tp:member-ref>, which is
        unimplemented and deprecated.
      </tp:deprecated>
      <tp:added version="0.17.17"/>
      <tp:docstring>
        The index of a message part within a message.
      </tp:docstring>
    </tp:simple-type>

    <tp:mapping name="Message_Part_Content_Map">
      <tp:added version="0.17.17"/>
      <tp:deprecated version="0.21.5">
        This structure is only used by
        <tp:member-ref>GetPendingMessageContent</tp:member-ref>, which is
        unimplemented and deprecated.
      </tp:deprecated>
      <tp:docstring>
        A mapping from message part indexes to their content, as returned by
        <tp:member-ref>GetPendingMessageContent</tp:member-ref>.
      </tp:docstring>

      <tp:member type="u" tp:type="Message_Part_Index" name="Part">
        <tp:docstring>
          Indexes into the array of <tp:type>Message_Part</tp:type>s that
          represents a message. The "headers" part (which is not a valid
          argument to GetPendingMessageContent) is considered to be part 0,
          so the valid part numbers start at 1 (for the second message part).
        </tp:docstring>
      </tp:member>

      <tp:member type="v" name="Content">
        <tp:docstring>
          The message part's content. The variant MUST contain either type
          's' or 'ay' (UTF-8 text string, or byte array), following the
          same rules as for the value of the 'content' key in
          the <tp:type>Message_Part</tp:type> mappings.
        </tp:docstring>
      </tp:member>
    </tp:mapping>

    <tp:simple-type type="s" name="Protocol_Message_Token"
                    array-name="Protocol_Message_Token_List">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>An opaque token used to identify messages in the underlying.
          protocol. As a special case, the empty string indicates that there
          is no particular identification for a message.</p>

        <p>CM implementations SHOULD use an identifier expected to be unique,
          such as a UUID, for outgoing messages (if possible).</p>

        <p>Some protocols can only track a limited number of messages
          in a small message-ID space (SMS messages are identified by a single
          byte), and some implementations send non-unique identifiers (some
          XMPP clients use very simple message IDs, such as an incrementing
          integer that resets to 1 at the beginning of each connection). As a
          result, clients MUST NOT assume that protocol tokens will not be
          re-used.</p>

        <p>In particular, clients SHOULD use a heuristic to assign delivery
          reports to messages, such as matching on message content or
          timestamp (if available), or assuming that the delivery report
          refers to the most recent message with that ID.</p>
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type name="Protocol_Content_Identifier" type="s">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A protocol-specific identifier for a blob of content, as used for
          the <tt>identifier</tt> key in a <tp:type>Message_Part</tp:type>. The
          same identifier MAY be re-used if the same content, byte-for-byte,
          appears as a part of several messages.</p>

        <tp:rationale>
          <p>On XMPP, these identifiers might be Content-IDs for custom
            smileys implemented using <a
              href="http://xmpp.org/extensions/xep-0231.html">XEP-0232 Bits of
            Binary</a>; the same smiley might well appear in multiple
            messages.</p>
        </tp:rationale>
      </tp:docstring>
    </tp:simple-type>

    <method name="SendMessage" tp:name-for-bindings="Send_Message">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Submit a message to the server for sending.
          If this method returns successfully, the message has been submitted
          to the server and the <tp:member-ref>MessageSent</tp:member-ref>
          signal is emitted. A corresponding
          <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type.Text">Sent</tp:dbus-ref>
          signal on the Text interface MUST also be emitted.</p>

        <p>This method MUST return before the MessageSent signal is
          emitted.</p>

        <tp:rationale>
          <p>This means that the process sending the message is the first
            to see the <tp:type>Protocol_Message_Token</tp:type>, and can
            relate the message to the corresponding
            <tp:member-ref>MessageSent</tp:member-ref> signal by comparing
            message tokens (if supported by the protocol).</p>
        </tp:rationale>

        <p>If this method fails, message submission to the server has failed
          and no signal on this interface (or the Text interface) is
          emitted.</p>

        <p>If this method succeeds, message submission to the server has
          succeeded, but the message has not necessarily reached its intended
          recipient. If a delivery failure is detected later, this is
          signalled by receiving a message whose <code>message-type</code>
          header maps to
          <tp:value-ref type="Channel_Text_Message_Type">Delivery_Report</tp:value-ref>.
          Similarly, if delivery is detected to have been successful
          (which is not possible in all protocols), a successful delivery
          report will be signalled.</p>
      </tp:docstring>

      <arg direction="in" type="aa{sv}" tp:type="Message_Part[]"
        name="Message">
        <tp:docstring>
          The message content, including any attachments or alternatives.
          This MUST NOT include the following headers, or any others that
          do not make sense for a client to specify:
          <code>message-sender</code>, <code>message-sender-id</code>,
          <code>message-sent</code>, <code>message-received</code>,
          <code>pending-message-id</code>.
        </tp:docstring>
      </arg>
      <arg direction="in" name="Flags" type="u"
        tp:type="Message_Sending_Flags">
        <tp:docstring>
          Flags affecting how the message is sent. The channel MAY ignore some
          or all flags, depending on
          <tp:member-ref>DeliveryReportingSupport</tp:member-ref>; the flags
          that were handled by the CM are provided in
          <tp:member-ref>MessageSent</tp:member-ref>.
        </tp:docstring>
      </arg>

      <arg direction="out" type="s" tp:type="Protocol_Message_Token"
        name="Token">
        <tp:docstring>
          An opaque token used to match any incoming delivery or failure
          reports against this message, or an empty string if the message
          is not readily identifiable.
        </tp:docstring>
      </arg>

      <tp:possible-errors>
        <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
          <tp:docstring>
            The requested message is malformed and cannot be sent.
          </tp:docstring>
        </tp:error>
        <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
        <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
        <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
      </tp:possible-errors>
    </method>

    <tp:flags name="Message_Sending_Flags" value-prefix="Message_Sending_Flag"
      type="u">
      <tp:docstring>
        Flags altering the way a message is sent. The "most usual" action
        should always be to have these flags unset. Some indication of which
        flags are supported is provided by the
        <tp:member-ref>DeliveryReportingSupport</tp:member-ref> property.
      </tp:docstring>

      <tp:flag suffix="Report_Delivery" value="1">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Provide a successful delivery report if possible, even if this is
            not the default for this protocol. Ignored if delivery reports are
            not possible on this protocol.</p>

          <tp:rationale>
            <p>In some protocols, like XMPP, it is not conventional to request
              or send positive delivery notifications.</p>
          </tp:rationale>

          <p>Delivery failure reports SHOULD always be sent, but if this flag
            is present, the connection manager MAY also try harder to obtain
            failed delivery reports or allow them to be matched to outgoing
            messages.</p>
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Report_Read" value="2">
        <tp:added version="0.19.9"/>
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Provide a delivery report when the message is read by the
            recipient, even if this is not the default for this protocol.
            Ignored if read reports are not possible on this protocol.</p>
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Report_Deleted" value="4">
        <tp:added version="0.19.9"/>
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Provide a delivery report when the message is deleted by the
            recipient, even if this is not the default for this protocol.
            Ignored if such reports are not possible on this protocol.</p>
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <signal name="MessageSent" tp:name-for-bindings="Message_Sent">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Signals that a message has been submitted for sending. This
          MUST be emitted exactly once per emission of the <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type.Text">Sent</tp:dbus-ref>
          signal on the Text interface, for backwards-compatibility; clients
          SHOULD ignore the latter if this interface is present, as mentioned
          in the introduction.</p>

        <p>This SHOULD be emitted as soon as the CM determines it's
          theoretically possible to send the message (e.g. the parameters are
          supported and correct).</p>

        <tp:rationale>
          <p>This signal allows a process that is not the caller of
            SendMessage to log sent messages.</p>
        </tp:rationale>
      </tp:docstring>

      <arg type="aa{sv}" tp:type="Message_Part[]" name="Content">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>The message content (see <tp:type>Message_Part</tp:type> for full
            details). If the message that was passed to
            <tp:member-ref>SendMessage</tp:member-ref> has a formatted text
            part that the connection manager recognises, but no
            <tt>text/plain</tt> alternative, the CM MUST use the formatted text
            part to generate a <tt>text/plain</tt> alternative which is also
            included in this signal argument.</p>

          <p>The connection manager SHOULD include the
            <code>message-sender</code>, <code>message-sender-id</code> and
            <code>message-sent</code> headers in the representation of the
            message that is signalled here. If the channel has
            channel-specific handles, the <code>message-sender</code> and
            <code>message-sender-id</code> SHOULD reflect the sender that
            other contacts will see.</p>

          <p>If the connection manager can predict that the message will be
            altered during transmission, this argument SHOULD reflect what
            other contacts will receive, rather than being a copy of the
            argument to SendMessage (if the message is truncated,
            formatting or alternatives are dropped, etc., then the edited
            version SHOULD appear in this signal).</p>
        </tp:docstring>
      </arg>

      <arg name="Flags" type="u" tp:type="Message_Sending_Flags">
        <tp:docstring>
          <p>Flags affecting how the message was sent.  The flags might be a
            subset of those passed to SendMessage if the caller requested
            unsupported flags.</p>
        </tp:docstring>
      </arg>

      <arg name="Message_Token" type="s" tp:type="Protocol_Message_Token">
        <tp:docstring>
          An opaque token used to match any incoming delivery or failure
          reports against this message, or an empty string if the message
          is not readily identifiable.
        </tp:docstring>
      </arg>
    </signal>

    <property name="PendingMessages" type="aaa{sv}" access="read"
      tp:type="Message_Part[][]" tp:name-for-bindings="Pending_Messages">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of incoming messages that have neither been acknowledged nor
          rejected. This list is a more detailed version of the one returned
          by <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type">Text.ListPendingMessages</tp:dbus-ref>,
          and contains the same messages, uniquely identified by the same
          pending message IDs. Its items can be removed using
          <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type">Text.AcknowledgePendingMessages</tp:dbus-ref>.</p>

        <p>Change notification is via
          <tp:member-ref>MessageReceived</tp:member-ref> and
          <tp:member-ref>PendingMessagesRemoved</tp:member-ref>.</p>
      </tp:docstring>
    </property>

    <signal name="PendingMessagesRemoved"
      tp:name-for-bindings="Pending_Messages_Removed">
      <tp:docstring>
        The messages with the given IDs have been removed from the
        <tp:member-ref>PendingMessages</tp:member-ref> list. Clients SHOULD NOT
        attempt to acknowledge those messages.

        <tp:rationale>
          This completes change notification for the PendingMessages property
          (previously, there was change notification when pending messages
          were added, but not when they were removed).
        </tp:rationale>
      </tp:docstring>

      <arg name="Message_IDs" type="au" tp:type="Message_ID[]">
        <tp:docstring>
          The messages that have been removed from the pending message list.
        </tp:docstring>
      </arg>
    </signal>

    <method name="GetPendingMessageContent"
      tp:name-for-bindings="Get_Pending_Message_Content">
      <tp:deprecated version='0.21.5'
                     xmlns="http://www.w3.org/1999/xhtml">
        This method has never been implemented, and in any case would have been
        impossible to use correctly when multiple clients (such as a logger and
        the handler) are interested in a text channel. See <a
          href='https://bugs.freedesktop.org/show_bug.cgi?id=26417'>freedesktop.org
        bug #26417</a> for more details.
      </tp:deprecated>
      <tp:docstring>
        Retrieve the content of one or more parts of a pending message.
        Note that this function may take a considerable amount of time
        to return if the part's 'needs-retrieval' flag is true; consider
        extending the default D-Bus method call timeout. Additional API is
        likely to be added in future, to stream large message parts.
      </tp:docstring>

      <arg name="Message_ID" type="u" tp:type="Message_ID" direction="in">
        <tp:docstring>
          The ID of a pending message
        </tp:docstring>
      </arg>

      <arg name="Parts" type="au" direction="in"
        tp:type="Message_Part_Index[]">
        <tp:docstring>
          The desired entries in the array of message parts, identified by
          their position. The "headers" part (which is not a valid argument
          to this method) is considered to be part 0, so the valid part
          numbers start at 1 (for the second Message_Part).
        </tp:docstring>
      </arg>

      <arg name="Content" type="a{uv}" direction="out"
        tp:type="Message_Part_Content_Map">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>The content of the requested parts. The keys in this mapping
            are positions in the array of message parts; the values are
            either of type 's' or 'ay' (UTF-8 text string, or byte array),
            following the same rules as for the value of the 'content' key in
            the <tp:type>Message_Part</tp:type> mappings.</p>

          <p>If the one of the requested part numbers was greater than zero
            but referred to a part that had no content (i.e. it had no
            'content-type' key or no 'content' key), it is simply omitted from
            this mapping; this is not considered to be an error condition.</p>
        </tp:docstring>
      </arg>

      <tp:possible-errors>
        <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
          <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
            Either there is no pending message with the given message ID,
            or one of the part numbers given was 0 or too large.
          </tp:docstring>
        </tp:error>
        <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
        <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
        <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
      </tp:possible-errors>
    </method>

    <signal name="MessageReceived" tp:name-for-bindings="Message_Received">
      <tp:docstring>
        Signals that a message has been received and added to the pending
        messages queue. This MUST be emitted exactly once per emission of the
        <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type.Text">Received</tp:dbus-ref>
        signal on the Text interface, for backwards-compatibility; clients
        SHOULD ignore the latter in favour of this signal if this interface is
        present, as mentioned in the introduction.
      </tp:docstring>

      <arg type="aa{sv}" tp:type="Message_Part[]" name="Message">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>The message content, including any attachments or alternatives. If
            the incoming message contains formatted text without a plain text
            alternative, the connection manager MUST generate a
            <tt>text/plain</tt> alternative from the formatted text, and
            include it in this message (both here, and in the
            <tp:member-ref>PendingMessages</tp:member-ref> property).</p>
        </tp:docstring>
      </arg>
    </signal>

    <tp:enum name="Delivery_Status" value-prefix="Delivery_Status"
      plural="Delivery_Statuses" type="u">
      <tp:docstring>
        <p>The status of a message as indicated by a delivery report.</p>

        <p>If this enum is extended in future specifications, this should
          only be to add new, non-overlapping conditions (i.e. all failures
          should still be signalled as either Temporarily_Failed
          or Permanently_Failed). If additional detail is required (e.g.
          distinguishing between the various types of permanent failure) this
          will be done using additional
          <tp:type>Delivery_Report_Header_Key</tp:type>s.</p>
      </tp:docstring>

      <tp:enumvalue suffix="Unknown" value="0">
        <tp:docstring>
          The message's disposition is unknown.
          Clients SHOULD consider all messages to have status
          Delivery_Status_Unknown unless otherwise specified; connection
          managers SHOULD NOT signal this delivery status explicitly.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Delivered" value="1">
        <tp:docstring>
          The message has been delivered to the intended recipient.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Temporarily_Failed" value="2">
        <tp:docstring>
          Delivery of the message has failed. Clients SHOULD notify the user,
          but MAY automatically try sending another copy of the message.

          <tp:rationale>
            Similar to errors with type="wait" in XMPP; analogous to
            4xx errors in SMTP.
          </tp:rationale>
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Permanently_Failed" value="3">
        <tp:docstring>
          Delivery of the message has failed. Clients SHOULD NOT try again
          unless by specific user action. If the user does not modify the
          message or alter configuration before re-sending, this error is
          likely to happen again.

          <tp:rationale>
            Similar to errors with type="cancel", type="modify"
            or type="auth" in XMPP; analogous to 5xx errors in SMTP.
          </tp:rationale>
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Accepted" value="4">
        <tp:docstring>
          An intermediate server has accepted the message but the message
          has not been yet delivered to the ultimate recipient. The
          connection manager might send a Failed report or Delivered report
          later.

          <tp:rationale>
            Similar to "202 Accepted" success code in SIP; analogous to
            251 and 252 responses in SMTP.
          </tp:rationale>
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Read" value="5">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          The message has been read by the intended recipient.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Deleted" value="6">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          The message has been deleted by the intended recipient. This MAY be
          signalled on its own if the message is deleted without being read, or
          after <code>Read</code> if the message was read before being deleted.
        </tp:docstring>
      </tp:enumvalue>
    </tp:enum>

    <tp:flags name="Delivery_Reporting_Support_Flags"
      value-prefix="Delivery_Reporting_Support_Flag" type="u">
      <tp:docstring>
        Flags indicating the level of support for delivery reporting on this
        channel, as found on the
        <tp:member-ref>DeliveryReportingSupport</tp:member-ref> property. Any
        future flags added to this set will conform to the
        convention that the presence of an extra flag implies that
        more operations will succeed. Note that CMs may always provide more
        reports than are requested in the
        <tp:type>Message_Sending_Flags</tp:type> passed to
        <tp:member-ref>SendMessage</tp:member-ref>.

        <tp:rationale>
          If senders want delivery reports, they should ask for them.  If they
          don't want delivery reports, they can just ignore them, so there's no
          need to have capability discovery for what will happen if a delivery
          report isn't requested.
        </tp:rationale>
      </tp:docstring>

      <tp:flag suffix="Receive_Failures" value="1">
        <tp:docstring>
          Clients MAY expect to receive negative delivery reports if
          Message_Sending_Flag_Report_Delivery is specified when sending.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Receive_Successes" value="2">
        <tp:docstring>
          Clients MAY expect to receive positive delivery reports if
          Message_Sending_Flag_Report_Delivery is specified when sending.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Receive_Read" value="4">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          Clients MAY expect to receive <tp:type>Delivery_Status</tp:type>
          <code>Read</code> reports if Message_Sending_Flag_Report_Read
          is specified when sending.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Receive_Deleted" value="8">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          Clients MAY expect to receive <tp:type>Delivery_Status</tp:type>
          <code>Deleted</code> reports if Message_Sending_Flag_Report_Deleted
          is specified when sending.
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <property name="DeliveryReportingSupport" access="read"
      tp:type="Delivery_Reporting_Support_Flags" type="u"
      tp:name-for-bindings="Delivery_Reporting_Support"
      tp:immutable="yes">
      <tp:docstring>
        A bitfield indicating features supported by this channel.
      </tp:docstring>
    </property>

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