summaryrefslogtreecommitdiff
path: root/pjsip/include/pjsua2/call.hpp
blob: c4978e38933e302f39eda079828923f6e8606f96 (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
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
/* $Id$ */
/*
 * Copyright (C) 2012-2013 Teluu Inc. (http://www.teluu.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#ifndef __PJSUA2_CALL_HPP__
#define __PJSUA2_CALL_HPP__

/**
 * @file pjsua2/call.hpp
 * @brief PJSUA2 Call manipulation
 */
#include <pjsua-lib/pjsua.h>
#include <pjsua2/media.hpp>

/** PJSUA2 API is inside pj namespace */
namespace pj
{

/**
 * @defgroup PJSUA2_CALL Call
 * @ingroup PJSUA2_Ref
 */

/**
 * @defgroup PJSUA2_Call_Data_Structure Call Related Types
 * @ingroup PJSUA2_DS
 * @{
 */

using std::string;
using std::vector;

//////////////////////////////////////////////////////////////////////////////

/**
 * Codec parameters, corresponds to pjmedia_codec_param or
 * pjmedia_vid_codec_param.
 */
typedef void *CodecParam;

/**
 * Media stream, corresponds to pjmedia_stream
 */
typedef void *MediaStream;

/**
 * Media transport, corresponds to pjmedia_transport
 */
typedef void *MediaTransport;

/**
 * This structure describes statistics state.
 */
struct MathStat
{
    int n;      /**< number of samples  */
    int max;    /**< maximum value      */
    int min;    /**< minimum value      */
    int last;   /**< last value         */
    int mean;   /**< mean               */

public:
    /**
     * Default constructor
     */
    MathStat();
    
    /**
     * Convert from pjsip
     */
    void fromPj(const pj_math_stat &prm);
};

/**
 * Unidirectional RTP stream statistics.
 */
struct RtcpStreamStat
{
    TimeValue	    update;	/**< Time of last update.		    */
    unsigned	    updateCount;/**< Number of updates (to calculate avg)   */
    unsigned	    pkt;	/**< Total number of packets		    */
    unsigned	    bytes;	/**< Total number of payload/bytes	    */
    unsigned	    discard;	/**< Total number of discarded packets.	    */
    unsigned	    loss;	/**< Total number of packets lost	    */
    unsigned	    reorder;	/**< Total number of out of order packets   */
    unsigned	    dup;	/**< Total number of duplicates packets	    */
    
    MathStat        lossPeriodUsec; /**< Loss period statistics 	    */

    struct {
        unsigned    burst;	/**< Burst/sequential packet lost detected  */
        unsigned    random;	/**< Random packet lost detected.	    */
    } lossType;                 /**< Types of loss detected.                */
    
    MathStat        jitterUsec;	/**< Jitter statistics                      */
    
public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjmedia_rtcp_stream_stat &prm);
};

/**
 * RTCP SDES structure.
 */
struct RtcpSdes
{
    string	cname;		/**< RTCP SDES type CNAME.	*/
    string	name;		/**< RTCP SDES type NAME.	*/
    string	email;		/**< RTCP SDES type EMAIL.	*/
    string	phone;		/**< RTCP SDES type PHONE.	*/
    string	loc;		/**< RTCP SDES type LOC.	*/
    string	tool;		/**< RTCP SDES type TOOL.	*/
    string	note;		/**< RTCP SDES type NOTE.	*/

public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjmedia_rtcp_sdes &prm);
};
    
/**
 * Bidirectional RTP stream statistics.
 */
struct RtcpStat
{
    TimeValue           start;          /**< Time when session was created  */
    
    RtcpStreamStat      txStat;         /**< Encoder stream statistics.	    */
    RtcpStreamStat      rxStat;         /**< Decoder stream statistics.	    */
    
    MathStat            rttUsec;        /**< Round trip delay statistic.    */
    
    pj_uint32_t		rtpTxLastTs;    /**< Last TX RTP timestamp.         */
    pj_uint16_t		rtpTxLastSeq;   /**< Last TX RTP sequence.          */

    MathStat            rxIpdvUsec;     /**< Statistics of IP packet delay
                                             variation in receiving
                                             direction. It is only used when
                                             PJMEDIA_RTCP_STAT_HAS_IPDV is
                                             set to non-zero.               */

    MathStat            rxRawJitterUsec;/**< Statistic of raw jitter in
                                             receiving direction. It is only 
                                             used when
                                             PJMEDIA_RTCP_STAT_HAS_RAW_JITTER
                                             is set to non-zero.            */
    
    RtcpSdes            peerSdes;       /**< Peer SDES.			    */

public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjmedia_rtcp_stat &prm);
};

/**
 * This structure describes jitter buffer state.
 */
struct JbufState
{
    /* Setting */
    unsigned	frameSize;	    /**< Individual frame size, in bytes.   */
    unsigned	minPrefetch;	    /**< Minimum allowed prefetch, in frms. */
    unsigned	maxPrefetch;	    /**< Maximum allowed prefetch, in frms. */
    
    /* Status */
    unsigned	burst;		    /**< Current burst level, in frames	    */
    unsigned	prefetch;	    /**< Current prefetch value, in frames  */
    unsigned	size;		    /**< Current buffer size, in frames.    */
    
    /* Statistic */
    unsigned	avgDelayMsec;	    /**< Average delay, in ms.		    */
    unsigned	minDelayMsec;	    /**< Minimum delay, in ms.		    */
    unsigned	maxDelayMsec;	    /**< Maximum delay, in ms.		    */
    unsigned	devDelayMsec;	    /**< Standard deviation of delay, in ms.*/
    unsigned	avgBurst;	    /**< Average burst, in frames.	    */
    unsigned	lost;		    /**< Number of lost frames.		    */
    unsigned	discard;	    /**< Number of discarded frames.	    */
    unsigned	empty;		    /**< Number of empty on GET events.	    */
    
public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjmedia_jb_state &prm);
};

/**
 * This structure describes SDP session description. It corresponds to the
 * pjmedia_sdp_session structure.
 */
struct SdpSession
{
    /**
     * The whole SDP as a string.
     */
    string  wholeSdp;
    
    /**
     * Pointer to its original pjmedia_sdp_session. Only valid when the struct
     * is converted from PJSIP's pjmedia_sdp_session.
     */
    void   *pjSdpSession;

public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjmedia_sdp_session &sdp);
};

/**
 * This structure describes a media format changed event.
 */
struct MediaFmtChangedEvent
{
    unsigned newWidth;      /**< The new width.     */
    unsigned newHeight;     /**< The new height.    */
};

/**
 * This structure describes a media event. It corresponds to the
 * pjmedia_event structure.
 */
struct MediaEvent
{
    /**
     * The event type.
     */
    pjmedia_event_type          type;

    /**
     * Additional data/parameters about the event. The type of data
     * will be specific to the event type being reported.
     */
    union {
	/**
         * Media format changed event data.
         */
	MediaFmtChangedEvent    fmtChanged;
        
	/**
         * Pointer to storage to user event data, if it's outside
	 * this struct
	 */
	GenericData		ptr;
    } data;
    
    /**
     * Pointer to original pjmedia_event. Only valid when the struct
     * is converted from PJSIP's pjmedia_event.
     */
    void                       *pjMediaEvent;

public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjmedia_event &ev);
};

/**
 * This structure describes media transport informations. It corresponds to the
 * pjmedia_transport_info structure.
 */
struct MediaTransportInfo
{
    /**
     * Remote address where RTP originated from.
     */
    SocketAddress   srcRtpName;

    /**
     * Remote address where RTCP originated from.
     */
    SocketAddress   srcRtcpName;
    
public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjmedia_transport_info &info);
};

//////////////////////////////////////////////////////////////////////////////

/**
 * Call settings.
 */
struct CallSetting
{
    /**
     * Bitmask of pjsua_call_flag constants.
     *
     * Default: PJSUA_CALL_INCLUDE_DISABLED_MEDIA
     */
    unsigned	    flag;
    
    /**
     * This flag controls what methods to request keyframe are allowed on
     * the call. Value is bitmask of pjsua_vid_req_keyframe_method.
     *
     * Default: PJSUA_VID_REQ_KEYFRAME_SIP_INFO |
     *          PJSUA_VID_REQ_KEYFRAME_RTCP_PLI
     */
    unsigned	    reqKeyframeMethod;
    
    /**
     * Number of simultaneous active audio streams for this call. Setting
     * this to zero will disable audio in this call.
     *
     * Default: 1
     */
    unsigned        audioCount;
    
    /**
     * Number of simultaneous active video streams for this call. Setting
     * this to zero will disable video in this call.
     *
     * Default: 1 (if video feature is enabled, otherwise it is zero)
     */
    unsigned        videoCount;
    
public:
    /**
     * Default constructor initializes with empty or default values.
     */
    CallSetting(pj_bool_t useDefaultValues = false);

    /**
     * Check if the settings are set with empty values.
     *
     * @return      True if the settings are empty.
     */
    bool isEmpty() const;

    /**
     * Convert from pjsip
     */
    void fromPj(const pjsua_call_setting &prm);

    /**
     * Convert to pjsip
     */
    pjsua_call_setting toPj() const;
};

/**
 * Call media information.
 */
struct CallMediaInfo
{
    /**
     * Media index in SDP.
     */
    unsigned                index;
    
    /**
     * Media type.
     */
    pjmedia_type            type;
    
    /**
     * Media direction.
     */
    pjmedia_dir             dir;
    
    /**
     * Call media status.
     */
    pjsua_call_media_status status;
    
    /**
     * The conference port number for the call. Only valid if the media type
     * is audio.
     */
    int                     audioConfSlot;
    
    /**
     * The window id for incoming video, if any, or
     * PJSUA_INVALID_ID. Only valid if the media type is video.
     */
    pjsua_vid_win_id	    videoIncomingWindowId;
    
    /**
     * The video capture device for outgoing transmission, if any,
     * or PJMEDIA_VID_INVALID_DEV. Only valid if the media type is video.
     */
    pjmedia_vid_dev_index   videoCapDev;
    
public:
    /**
     * Default constructor
     */
    CallMediaInfo();
    
    /**
     * Convert from pjsip
     */
    void fromPj(const pjsua_call_media_info &prm);
};
    
/** Array of call media info */
typedef std::vector<CallMediaInfo> CallMediaInfoVector;

/**
 * Call information. Application can query the call information
 * by calling Call::getInfo().
 */
struct CallInfo
{
    /**
     * Call identification.
     */
    pjsua_call_id	id;
    
    /**
     * Initial call role (UAC == caller)
     */
    pjsip_role_e	role;
    
    /**
     * The account ID where this call belongs.
     */
    pjsua_acc_id	accId;
    
    /**
     * Local URI
     */
    string		localUri;
    
    /**
     * Local Contact
     */
    string		localContact;
    
    /**
     * Remote URI
     */
    string		remoteUri;
    
    /**
     * Remote contact
     */
    string		remoteContact;
    
    /**
     * Dialog Call-ID string.
     */
    string		callIdString;
    
    /**
     * Call setting
     */
    CallSetting         setting;
    
    /**
     * Call state
     */
    pjsip_inv_state	state;
    
    /**
     * Text describing the state
     */
    string		stateText;
    
    /**
     * Last status code heard, which can be used as cause code
     */
    pjsip_status_code	lastStatusCode;
    
    /**
     * The reason phrase describing the last status.
     */
    string		lastReason;
    
    /**
     * Array of active media information.
     */
    CallMediaInfoVector media;

    /**
     * Array of provisional media information. This contains the media info
     * in the provisioning state, that is when the media session is being
     * created/updated (SDP offer/answer is on progress).
     */
    CallMediaInfoVector provMedia;
    
    /**
     * Up-to-date call connected duration (zero when call is not
     * established)
     */
    TimeValue		connectDuration;
    
    /**
     * Total call duration, including set-up time
     */
    TimeValue		totalDuration;
    
    /**
     * Flag if remote was SDP offerer
     */
    bool		remOfferer;
    
    /**
     * Number of audio streams offered by remote
     */
    unsigned		remAudioCount;
    
    /**
     * Number of video streams offered by remote
     */
    unsigned		remVideoCount;

public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjsua_call_info &pci);
};

/**
 * Media stream info.
 */
struct StreamInfo
{
    /**
     * Media type of this stream.
     */
    pjmedia_type        type;

    /**
     * Transport protocol (RTP/AVP, etc.)
     */
    pjmedia_tp_proto	proto;
    
    /**
     * Media direction.
     */
    pjmedia_dir		dir;
    
    /**
     * Remote RTP address
     */
    SocketAddress	remoteRtpAddress;
    
    /**
     * Optional remote RTCP address
     */
    SocketAddress	remoteRtcpAddress;
    
    /**
     * Outgoing codec payload type.
     */
    unsigned		txPt;
    
    /**
     * Incoming codec payload type.
     */
    unsigned		rxPt;
    
    /**
     * Codec name.
     */
    string              codecName;
    
    /**
     * Codec clock rate.
     */
    unsigned            codecClockRate;
    
    /**
     * Optional codec param.
     */
    CodecParam          codecParam;

public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjsua_stream_info &info);
};

/**
 * Media stream statistic.
 */
struct StreamStat
{
    /**
     * RTCP statistic.
     */
    RtcpStat	rtcp;
    
    /**
     * Jitter buffer statistic.
     */
    JbufState	jbuf;

public:
    /**
     * Convert from pjsip
     */
    void fromPj(const pjsua_stream_stat &prm);
};

/**
 * This structure contains parameters for Call::onCallState() callback.
 */
struct OnCallStateParam
{
    /**
     * Event which causes the call state to change.
     */
    SipEvent    e;
};

/**
 * This structure contains parameters for Call::onCallTsxState() callback.
 */
struct OnCallTsxStateParam
{
    /**
     * Transaction event that caused the state change.
     */
    SipEvent    e;
};

/**
 * This structure contains parameters for Call::onCallMediaState() callback.
 */
struct OnCallMediaStateParam
{
};

/**
 * This structure contains parameters for Call::onCallSdpCreated() callback.
 */
struct OnCallSdpCreatedParam
{
    /**
     * The SDP has just been created.
     */
    SdpSession sdp;

    /**
     * The remote SDP, will be empty if local is SDP offerer.
     */
    SdpSession remSdp;
};

/**
 * This structure contains parameters for Call::onStreamCreated()
 * callback.
 */
struct OnStreamCreatedParam
{
    /**
     * Media stream.
     */
    MediaStream stream;
    
    /**
     * Stream index in the media session.
     */
    unsigned    streamIdx;
    
    /**
     * On input, it specifies the media port of the stream. Application
     * may modify this pointer to point to different media port to be
     * registered to the conference bridge.
     */
    MediaPort   pPort;
};

/**
 * This structure contains parameters for Call::onStreamDestroyed()
 * callback.
 */
struct OnStreamDestroyedParam
{
    /**
     * Media stream.
     */
    MediaStream stream;
    
    /**
     * Stream index in the media session.
     */
    unsigned    streamIdx;
};

/**
 * This structure contains parameters for Call::onDtmfDigit()
 * callback.
 */
struct OnDtmfDigitParam
{
    /**
     * DTMF ASCII digit.
     */
    string      digit;
};

/**
 * This structure contains parameters for Call::onCallTransferRequest()
 * callback.
 */
struct OnCallTransferRequestParam
{
    /**
     * The destination where the call will be transferred to.
     */
    string              dstUri;
    
    /**
     * Status code to be returned for the call transfer request. On input,
     * it contains status code 200.
     */
    pjsip_status_code   statusCode;
    
    /**
     * The current call setting, application can update this setting
     * for the call being transferred.
     */
    CallSetting         opt;
};

/**
 * This structure contains parameters for Call::onCallTransferStatus()
 * callback.
 */
struct OnCallTransferStatusParam
{
    /**
     * Status progress of the transfer request.
     */
    pjsip_status_code   statusCode;
    
    /**
     * Status progress reason.
     */
    string              reason;
    
    /**
     * If true, no further notification will be reported. The statusCode
     * specified in this callback is the final status.
     */
    bool                finalNotify;
    
    /**
     * Initially will be set to true, application can set this to false
     * if it no longer wants to receive further notification (for example,
     * after it hangs up the call).
     */
    bool                cont;
};

/**
 * This structure contains parameters for Call::onCallReplaceRequest()
 * callback.
 */
struct OnCallReplaceRequestParam
{
    /**
     * The incoming INVITE request to replace the call.
     */
    SipRxData           rdata;
    
    /**
     * Status code to be set by application. Application should only
     * return a final status (200-699)
     */
    pjsip_status_code   statusCode;
    
    /**
     * Optional status text to be set by application.
     */
    string              reason;
    
    /**
     * The current call setting, application can update this setting for
     * the call being replaced.
     */
    CallSetting         opt;
};

/**
 * This structure contains parameters for Call::onCallReplaced() callback.
 */
struct OnCallReplacedParam
{
    /**
     * The new call id.
     */
    pjsua_call_id       newCallId;
};

/**
 * This structure contains parameters for Call::onCallRxOffer() callback.
 */
struct OnCallRxOfferParam
{
    /**
     * The new offer received.
     */
    SdpSession          offer;
    
    /**
     * Status code to be returned for answering the offer. On input,
     * it contains status code 200. Currently, valid values are only
     * 200 and 488.
     */
    pjsip_status_code   statusCode;
    
    /**
     * The current call setting, application can update this setting for
     * answering the offer.
     */
    CallSetting         opt;
};

/**
 * This structure contains parameters for Call::onCallRedirected() callback.
 */
struct OnCallRedirectedParam
{
    /**
     * The current target to be tried.
     */
    string          targetUri;
    
    /**
     * The event that caused this callback to be called.
     * This could be the receipt of 3xx response, or 4xx/5xx response
     * received for the INVITE sent to subsequent targets, or empty
     * (e.type == PJSIP_EVENT_UNKNOWN)
     * if this callback is called from within Call::processRedirect()
     * context.
     */
    SipEvent        e;
};

/**
 * This structure contains parameters for Call::onCallMediaEvent() callback.
 */
struct OnCallMediaEventParam
{
    /**
     * The media stream index.
     */
    unsigned        medIdx;
    
    /**
     * The media event.
     */
    MediaEvent      ev;
};

/**
 * This structure contains parameters for Call::onCallMediaTransportState()
 * callback.
 */
struct OnCallMediaTransportStateParam
{
    /**
     * The media index.
     */
    unsigned        medIdx;
    
    /**
     * The media transport state
     */
    pjsua_med_tp_st state;
    
    /**
     * The last error code related to the media transport state.
     */
    pj_status_t     status;
    
    /**
     * Optional SIP error code.
     */
    int             sipErrorCode;
};

/**
 * This structure contains parameters for Call::onCreateMediaTransport()
 * callback.
 */
struct OnCreateMediaTransportParam
{
    /**
     * The media index in the SDP for which this media transport will be used.
     */
    unsigned        mediaIdx;
    
    /**
     * The media transport which otherwise will be used by the call has this
     * callback not been implemented. Application can change this to its own
     * instance of media transport to be used by the call.
     */
    MediaTransport  mediaTp;
    
    /**
     * Bitmask from pjsua_create_media_transport_flag.
     */
    unsigned        flags;
};

/**
 * @}  // PJSUA2_Call_Data_Structure
 */

/**
 * @addtogroup PJSUA2_CALL
 * @{
 */

/**
 * This structure contains parameters for Call::answer(), Call::hangup(),
 * Call::reinvite(), Call::update(), Call::xfer(), Call::xferReplaces(),
 * Call::setHold().
 */
struct CallOpParam
{
    /**
     * The call setting.
     */
    CallSetting         opt;
    
    /**
     * Status code.
     */
    pjsip_status_code   statusCode;
    
    /**
     * Reason phrase.
     */
    string              reason;
    
    /**
     * Options.
     */
    unsigned            options;
    
    /**
     * List of headers etc to be added to outgoing response message.
     * Note that this message data will be persistent in all next
     * answers/responses for this INVITE request.
     */
    SipTxOption         txOption;
    
public:
    /**
     * Default constructor initializes with zero/empty values.
     * Setting useDefaultCallSetting to true will initialize opt with default
     * call setting values.
     */
    CallOpParam(bool useDefaultCallSetting = false);
};

/**
 * This structure contains parameters for Call::sendRequest()
 */
struct CallSendRequestParam
{
    /**
     * SIP method of the request.
     */
    string       method;
    
    /**
     * Message body and/or list of headers etc to be included in
     * outgoing request.
     */
    SipTxOption  txOption;
    
public:
    /**
     * Default constructor initializes with zero/empty values.
     */
    CallSendRequestParam();
};

/**
 * This structure contains parameters for Call::vidSetStream()
 */
struct CallVidSetStreamParam
{
    /**
     * Specify the media stream index. This can be set to -1 to denote
     * the default video stream in the call, which is the first active
     * video stream or any first video stream if none is active.
     *
     * This field is valid for all video stream operations, except
     * PJSUA_CALL_VID_STRM_ADD.
     *
     * Default: -1 (first active video stream, or any first video stream
     *              if none is active)
     */
    int                     medIdx;
    
    /**
     * Specify the media stream direction.
     *
     * This field is valid for the following video stream operations:
     * PJSUA_CALL_VID_STRM_ADD and PJSUA_CALL_VID_STRM_CHANGE_DIR.
     *
     * Default: PJMEDIA_DIR_ENCODING_DECODING
     */
    pjmedia_dir             dir;
    
    /**
     * Specify the video capture device ID. This can be set to
     * PJMEDIA_VID_DEFAULT_CAPTURE_DEV to specify the default capture
     * device as configured in the account.
     *
     * This field is valid for the following video stream operations:
     * PJSUA_CALL_VID_STRM_ADD and PJSUA_CALL_VID_STRM_CHANGE_CAP_DEV.
     *
     * Default: PJMEDIA_VID_DEFAULT_CAPTURE_DEV.
     */
    pjmedia_vid_dev_index   capDev;
    
public:
    /**
     * Default constructor
     */
    CallVidSetStreamParam();
};

/**
 * Call.
 */
class Call
{
public:
    /**
     * Constructor.
     */
    Call(Account& acc, int call_id = PJSUA_INVALID_ID);

    /**
     * Destructor.
     */
    virtual ~Call();

    /**
     * Obtain detail information about this call.
     *
     * @return              Call info.
     */
    CallInfo getInfo() const throw(Error);
    
    /**
     * Check if this call has active INVITE session and the INVITE
     * session has not been disconnected.
     *
     * @return              True if call is active.
     */
    bool isActive() const;

    /**
     * Get PJSUA-LIB call ID or index associated with this call.
     *
     * @return              Integer greater than or equal to zero.
     */
    int getId() const;
    
    /**
     * Get the Call class for the specified call Id.
     *
     * @param call_id       The call ID to lookup
     *
     * @return              The Call instance or NULL if not found.
     */
    static Call *lookup(int call_id);

    /**
     * Check if call has an active media session.
     *
     * @return              True if yes.
     */
    bool hasMedia() const;
    
    /**
     * Get media for the specified media index.
     *
     * @param med_idx       Media index.
     *
     * @return              The media or NULL if invalid or inactive.
     */
    Media *getMedia(unsigned med_idx) const;

    /**
     * Check if remote peer support the specified capability.
     *
     * @param htype         The header type (pjsip_hdr_e) to be checked, which
     *                      value may be:
     *                      - PJSIP_H_ACCEPT
     *                      - PJSIP_H_ALLOW
     *                      - PJSIP_H_SUPPORTED
     * @param hname         If htype specifies PJSIP_H_OTHER, then the header
     *                      name must be supplied in this argument. Otherwise
     *                      the value must be set to empty string ("").
     * @param token         The capability token to check. For example, if \a
     *                      htype is PJSIP_H_ALLOW, then \a token specifies the
     *                      method names; if \a htype is PJSIP_H_SUPPORTED, then
     *                      \a token specifies the extension names such as
     *                      "100rel".
     *
     * @return              PJSIP_DIALOG_CAP_SUPPORTED if the specified
     *                      capability is explicitly supported, see
     *                      pjsip_dialog_cap_status for more info.
     */
    pjsip_dialog_cap_status remoteHasCap(int htype,
                                         const string &hname,
                                         const string &token) const;
    
    /**
     * Attach application specific data to the call. Application can then
     * inspect this data by calling getUserData().
     *
     * @param user_data     Arbitrary data to be attached to the call.
     */
    void setUserData(Token user_data);
    
    /**
     * Get user data attached to the call, which has been previously set with
     * setUserData().
     *
     * @return              The user data.
     */
    Token getUserData() const;
    
    /**
     * Get the NAT type of remote's endpoint. This is a proprietary feature
     * of PJSUA-LIB which sends its NAT type in the SDP when \a natTypeInSdp
     * is set in UaConfig.
     *
     * This function can only be called after SDP has been received from remote,
     * which means for incoming call, this function can be called as soon as
     * call is received as long as incoming call contains SDP, and for outgoing
     * call, this function can be called only after SDP is received (normally in
     * 200/OK response to INVITE). As a general case, application should call
     * this function after or in \a onCallMediaState() callback.
     *
     * @return              The NAT type.
     *
     * @see Endpoint::natGetType(), natTypeInSdp
     */
    pj_stun_nat_type getRemNatType() throw(Error);

    /**
     * Make outgoing call to the specified URI.
     *
     * @param dst_uri       URI to be put in the To header (normally is the same
     *                      as the target URI).
     * @param prm.opt       Optional call setting.
     * @param prm.txOption  Optional headers etc to be added to outgoing INVITE
     *                      request.
     */
    void makeCall(const string &dst_uri, const CallOpParam &prm) throw(Error);

    /**
     * Send response to incoming INVITE request with call setting param.
     * Depending on the status code specified as parameter, this function may
     * send provisional response, establish the call, or terminate the call.
     * Notes about call setting:
     *  - if call setting is changed in the subsequent call to this function,
     *    only the first call setting supplied will applied. So normally
     *    application will not supply call setting before getting confirmation
     *    from the user.
     *  - if no call setting is supplied when SDP has to be sent, i.e: answer
     *    with status code 183 or 2xx, the default call setting will be used,
     *    check CallSetting for its default values.
     *
     * @param prm.opt       Optional call setting.
     * @param prm.statusCode   Status code, (100-699).
     * @param prm.reason    Optional reason phrase. If empty, default text
     *                      will be used.
     * @param prm.txOption  Optional list of headers etc to be added to outgoing
     *                      response message. Note that this message data will
     *                      be persistent in all next answers/responses for this
     *                      INVITE request.
     */
    void answer(const CallOpParam &prm) throw(Error);
    
    /**
     * Hangup call by using method that is appropriate according to the
     * call state. This function is different than answering the call with
     * 3xx-6xx response (with answer()), in that this function
     * will hangup the call regardless of the state and role of the call,
     * while answer() only works with incoming calls on EARLY
     * state.
     *
     * @param prm.statusCode
     *                      Optional status code to be sent when we're rejecting
     *                      incoming call. If the value is zero, "603/Decline"
     *                      will be sent.
     * @param prm.reason    Optional reason phrase to be sent when we're
     *                      rejecting incoming call. If empty, default text
     *                      will be used.
     * @param prm.txOption  Optional list of headers etc to be added to outgoing
     *                      request/response message.
     */
    void hangup(const CallOpParam &prm) throw(Error);
    
    /**
     * Put the specified call on hold. This will send re-INVITE with the
     * appropriate SDP to inform remote that the call is being put on hold.
     * The final status of the request itself will be reported on the
     * \a onCallMediaState() callback, which inform the application that
     * the media state of the call has changed.
     *
     * @param prm.options   Bitmask of pjsua_call_flag constants. Currently,
     *                      only the flag PJSUA_CALL_UPDATE_CONTACT can be used.
     * @param prm.txOption  Optional message components to be sent with
     *                      the request.
     */
    void setHold(const CallOpParam &prm) throw(Error);
    
    /**
     * Send re-INVITE to release hold.
     * The final status of the request itself will be reported on the
     * \a onCallMediaState() callback, which inform the application that
     * the media state of the call has changed.
     *
     * @param prm.opt       Optional call setting, if empty, the current call
     *                      setting will remain unchanged.
     * @param prm.txOption  Optional message components to be sent with
     *                      the request.
     */
    void reinvite(const CallOpParam &prm) throw(Error);
    
    /**
     * Send UPDATE request.
     *
     * @param prm.opt       Optional call setting, if empty, the current call
     *                      setting will remain unchanged.
     * @param prm.txOption  Optional message components to be sent with
     *                      the request.
     */
    void update(const CallOpParam &prm) throw(Error);
    
    /**
     * Initiate call transfer to the specified address. This function will send
     * REFER request to instruct remote call party to initiate a new INVITE
     * session to the specified destination/target.
     *
     * If application is interested to monitor the successfulness and
     * the progress of the transfer request, it can implement
     * \a onCallTransferStatus() callback which will report the progress
     * of the call transfer request.
     *
     * @param dest          URI of new target to be contacted. The URI may be
     *                      in name address or addr-spec format.
     * @param prm.txOption  Optional message components to be sent with
     *                      the request.
     */
    void xfer(const string &dest, const CallOpParam &prm) throw(Error);

    /**
     * Initiate attended call transfer. This function will send REFER request
     * to instruct remote call party to initiate new INVITE session to the URL
     * of \a destCall. The party at \a dest_call then should "replace"
     * the call with us with the new call from the REFER recipient.
     *
     * @param dest_call     The call to be replaced.
     * @param prm.options   Application may specify
     *                      PJSUA_XFER_NO_REQUIRE_REPLACES to suppress the 
     *                      inclusion of "Require: replaces" in
     *                      the outgoing INVITE request created by the REFER
     *                      request.
     * @param prm.txOption  Optional message components to be sent with
     *                      the request.
     */
    void xferReplaces(const Call& dest_call,
                      const CallOpParam &prm) throw(Error);
    
    /**
     * Accept or reject redirection response. Application MUST call this
     * function after it signaled PJSIP_REDIRECT_PENDING in the 
     * \a onCallRedirected() callback,
     * to notify the call whether to accept or reject the redirection
     * to the current target. Application can use the combination of
     * PJSIP_REDIRECT_PENDING command in \a onCallRedirected() callback and
     * this function to ask for user permission before redirecting the call.
     *
     * Note that if the application chooses to reject or stop redirection (by
     * using PJSIP_REDIRECT_REJECT or PJSIP_REDIRECT_STOP respectively), the
     * call disconnection callback will be called before this function returns.
     * And if the application rejects the target, the \a onCallRedirected()
     * callback may also be called before this function returns if there is
     * another target to try.
     *
     * @param cmd           Redirection operation to be applied to the current
     *                      target. The semantic of this argument is similar
     *                      to the description in the \a onCallRedirected()
     *                      callback, except that the PJSIP_REDIRECT_PENDING is
     *                      not accepted here.
     */
    void processRedirect(pjsip_redirect_op cmd) throw(Error);

    /**
     * Send DTMF digits to remote using RFC 2833 payload formats.
     *
     * @param digits        DTMF string digits to be sent.
     */
    void dialDtmf(const string &digits) throw(Error);
    
    /**
     * Send instant messaging inside INVITE session.
     *
     * @param prm.contentType
     *                      MIME type.
     * @param prm.content   The message content.
     * @param prm.txOption  Optional list of headers etc to be included in
     *                      outgoing request. The body descriptor in the
     *                      txOption is ignored.
     * @param prm.userData  Optional user data, which will be given back when
     *                      the IM callback is called.
     */
    void sendInstantMessage(const SendInstantMessageParam& prm) throw(Error);
    
    /**
     * Send IM typing indication inside INVITE session.
     *
     * @param prm.isTyping  True to indicate to remote that local person is
     *                      currently typing an IM.
     * @param prm.txOption  Optional list of headers etc to be included in
     *                      outgoing request.
     */
    void sendTypingIndication(const SendTypingIndicationParam &prm)
         throw(Error);
    
    /**
     * Send arbitrary request with the call. This is useful for example to send
     * INFO request. Note that application should not use this function to send
     * requests which would change the invite session's state, such as
     * re-INVITE, UPDATE, PRACK, and BYE.
     *
     * @param prm.method    SIP method of the request.
     * @param prm.txOption  Optional message body and/or list of headers to be
     *                      included in outgoing request.
     */
    void sendRequest(const CallSendRequestParam &prm) throw(Error);
    
    /**
     * Dump call and media statistics to string.
     *
     * @param with_media    True to include media information too.
     * @param indent        Spaces for left indentation.
     *
     * @return              Call dump and media statistics string.
     */
    string dump(bool with_media, const string indent) throw(Error);
    
    /**
     * Get the media stream index of the default video stream in the call.
     * Typically this will just retrieve the stream index of the first
     * activated video stream in the call. If none is active, it will return
     * the first inactive video stream.
     *
     * @return              The media stream index or -1 if no video stream
     *                      is present in the call.
     */
    int vidGetStreamIdx() const;
    
    /**
     * Determine if video stream for the specified call is currently running
     * (i.e. has been created, started, and not being paused) for the specified
     * direction.
     *
     * @param med_idx       Media stream index, or -1 to specify default video
     *                      media.
     * @param dir           The direction to be checked.
     *
     * @return              True if stream is currently running for the
     *                      specified direction.
     */
    bool vidStreamIsRunning(int med_idx, pjmedia_dir dir) const;
    
    /**
     * Add, remove, modify, and/or manipulate video media stream for the
     * specified call. This may trigger a re-INVITE or UPDATE to be sent
     * for the call.
     *
     * @param op            The video stream operation to be performed,
     *                      possible values are pjsua_call_vid_strm_op.
     * @param param         The parameters for the video stream operation
     *                      (see CallVidSetStreamParam).
     */
    void vidSetStream(pjsua_call_vid_strm_op op,
                      const CallVidSetStreamParam &param) throw(Error);

    /**
     * Get media stream info for the specified media index.
     *
     * @param med_idx       Media stream index.
     *
     * @return              The stream info.
     */
    StreamInfo getStreamInfo(unsigned med_idx) const throw(Error);
    
    /**
     * Get media stream statistic for the specified media index.
     *
     * @param med_idx       Media stream index.
     *
     * @return              The stream statistic.
     */
    StreamStat getStreamStat(unsigned med_idx) const throw(Error);
    
    /**
     * Get media transport info for the specified media index.
     *
     * @param med_idx       Media stream index.
     *
     * @return              The transport info.
     */
    MediaTransportInfo getMedTransportInfo(unsigned med_idx) const throw(Error);

    /**
     * Internal function (callled by Endpoint( to process update to call
     * medias when call media state changes.
     */
    void processMediaUpdate(OnCallMediaStateParam &prm);

    /**
     * Internal function (called by Endpoint) to process call state change.
     */
    void processStateChange(OnCallStateParam &prm);
    
public:
    /*
     * Callbacks
     */
    /**
     * Notify application when call state has changed.
     * Application may then query the call info to get the
     * detail call states by calling getInfo() function.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallState(OnCallStateParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * This is a general notification callback which is called whenever
     * a transaction within the call has changed state. Application can
     * implement this callback for example to monitor the state of
     * outgoing requests, or to answer unhandled incoming requests
     * (such as INFO) with a final response.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallTsxState(OnCallTsxStateParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application when media state in the call has changed.
     * Normal application would need to implement this callback, e.g.
     * to connect the call's media to sound device. When ICE is used,
     * this callback will also be called to report ICE negotiation
     * failure.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallMediaState(OnCallMediaStateParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application when a call has just created a local SDP (for
     * initial or subsequent SDP offer/answer). Application can implement
     * this callback to modify the SDP, before it is being sent and/or
     * negotiated with remote SDP, for example to apply per account/call
     * basis codecs priority or to add custom/proprietary SDP attributes.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallSdpCreated(OnCallSdpCreatedParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application when media session is created and before it is
     * registered to the conference bridge. Application may return different
     * media port if it has added media processing port to the stream. This
     * media port then will be added to the conference bridge instead.
     *
     * @param prm	Callback parameter.
     */
    virtual void onStreamCreated(OnStreamCreatedParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application when media session has been unregistered from the
     * conference bridge and about to be destroyed.
     *
     * @param prm	Callback parameter.
     */
    virtual void onStreamDestroyed(OnStreamDestroyedParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application upon incoming DTMF digits.
     *
     * @param prm	Callback parameter.
     */
    virtual void onDtmfDigit(OnDtmfDigitParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application on call being transferred (i.e. REFER is received).
     * Application can decide to accept/reject transfer request
     * by setting the code (default is 202). When this callback
     * is not implemented, the default behavior is to accept the
     * transfer.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallTransferRequest(OnCallTransferRequestParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application of the status of previously sent call
     * transfer request. Application can monitor the status of the
     * call transfer request, for example to decide whether to
     * terminate existing call.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallTransferStatus(OnCallTransferStatusParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application about incoming INVITE with Replaces header.
     * Application may reject the request by setting non-2xx code.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallReplaceRequest(OnCallReplaceRequestParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application that an existing call has been replaced with
     * a new call. This happens when PJSUA-API receives incoming INVITE
     * request with Replaces header.
     *
     * After this callback is called, normally PJSUA-API will disconnect
     * this call and establish a new call \a newCallId.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallReplaced(OnCallReplacedParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application when call has received new offer from remote
     * (i.e. re-INVITE/UPDATE with SDP is received). Application can
     * decide to accept/reject the offer by setting the code (default
     * is 200). If the offer is accepted, application can update the
     * call setting to be applied in the answer. When this callback is
     * not implemented, the default behavior is to accept the offer using
     * current call setting.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallRxOffer(OnCallRxOfferParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application on incoming MESSAGE request.
     *
     * @param prm	Callback parameter.
     */
    virtual void onInstantMessage(OnInstantMessageParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application about the delivery status of outgoing MESSAGE
     * request.
     *
     * @param prm	Callback parameter.
     */
    virtual void onInstantMessageStatus(OnInstantMessageStatusParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notify application about typing indication.
     *
     * @param prm	Callback parameter.
     */
    virtual void onTypingIndication(OnTypingIndicationParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * This callback is called when the call is about to resend the
     * INVITE request to the specified target, following the previously
     * received redirection response.
     *
     * Application may accept the redirection to the specified target,
     * reject this target only and make the session continue to try the next
     * target in the list if such target exists, stop the whole
     * redirection process altogether and cause the session to be
     * disconnected, or defer the decision to ask for user confirmation.
     *
     * This callback is optional,
     * the default behavior is to NOT follow the redirection response.
     *
     * @param prm	Callback parameter.
     *
     * @return		Action to be performed for the target. Set this
     *			parameter to one of the value below:
     *			- PJSIP_REDIRECT_ACCEPT: immediately accept the
     *			  redirection. When set, the call will immediately
     *			  resend INVITE request to the target.
     *			- PJSIP_REDIRECT_ACCEPT_REPLACE: immediately accept
     *			  the redirection and replace the To header with the
     *			  current target. When set, the call will immediately
     *			  resend INVITE request to the target.
     *			- PJSIP_REDIRECT_REJECT: immediately reject this
     *			  target. The call will continue retrying with
     *			  next target if present, or disconnect the call
     *			  if there is no more target to try.
     *			- PJSIP_REDIRECT_STOP: stop the whole redirection
     *			  process and immediately disconnect the call. The
     *			  onCallState() callback will be called with
     *			  PJSIP_INV_STATE_DISCONNECTED state immediately
     *			  after this callback returns.
     *			- PJSIP_REDIRECT_PENDING: set to this value if
     *			  no decision can be made immediately (for example
     *			  to request confirmation from user). Application
     *			  then MUST call processRedirect()
     *			  to either accept or reject the redirection upon
     *			  getting user decision.
     */
    virtual pjsip_redirect_op onCallRedirected(OnCallRedirectedParam &prm)
    {
	PJ_UNUSED_ARG(prm);
        return PJSIP_REDIRECT_STOP;
    }
    
    /**
     * This callback is called when media transport state is changed.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallMediaTransportState(OnCallMediaTransportStateParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * Notification about media events such as video notifications. This
     * callback will most likely be called from media threads, thus
     * application must not perform heavy processing in this callback.
     * Especially, application must not destroy the call or media in this
     * callback. If application needs to perform more complex tasks to
     * handle the event, it should post the task to another thread.
     *
     * @param prm	Callback parameter.
     */
    virtual void onCallMediaEvent(OnCallMediaEventParam &prm)
    { PJ_UNUSED_ARG(prm); }
    
    /**
     * This callback can be used by application to implement custom media
     * transport adapter for the call, or to replace the media transport
     * with something completely new altogether.
     *
     * This callback is called when a new call is created. The library has
     * created a media transport for the call, and it is provided as the
     * \a mediaTp argument of this callback. The callback may change it
     * with the instance of media transport to be used by the call.
     *
     * @param prm	Callback parameter.
     */
    virtual void
    onCreateMediaTransport(OnCreateMediaTransportParam &prm)
    { PJ_UNUSED_ARG(prm); }

private:
    Account             &acc;
    pjsua_call_id 	 id;
    Token                userData;
    std::vector<Media *> medias;
};

/**
 * @}  // PJSUA2_CALL
 */

} // namespace pj

#endif	/* __PJSUA2_CALL_HPP__ */