This file is indexed.

/usr/include/ccrtp/iqueue.h is in libccrtp-dev 2.0.9-2.2+b2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   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
// Copyright (C) 2001,2002,2004 Federico Montesino Pouzols <fedemp@altern.org>.
//
// 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.
//
// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
//
// This exception applies only to the code released under the name GNU
// ccRTP.  If you copy code from other releases into a copy of GNU
// ccRTP, as the General Public License permits, the exception does
// not apply to the code that you add in this way.  To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own for GNU ccRTP, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice.
//

/**
 * @file iqueue.h
 *
 * @short Generic RTP input queues.
 **/

#ifndef CCXX_RTP_IQUEUE_H_
#define CCXX_RTP_IQUEUE_H_

#include <ccrtp/queuebase.h>
#include <ccrtp/CryptoContext.h>

#include <list>

NAMESPACE_COMMONCPP

/**
 * @defgroup iqueue Generic RTP input queues.
 * @{
 **/

/**
 * @class Members rtp.h
 * @short members and senders accounting
 *
 * Records the number of members as well as active senders. For now,
 * it is too simple.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
class __EXPORT Members
{
public:
    inline void
    setMembersCount(uint32 n)
    { members = n; }

    inline void
    increaseMembersCount()
    { members++; }

    inline void
    decreaseMembersCount()
    { members--; }

    inline uint32
    getMembersCount() const
    { return members; }

    inline void
    setSendersCount(uint32 n)
    { activeSenders = n; }

    inline void
    increaseSendersCount()
    { activeSenders++; }

    inline void
    decreaseSendersCount()
    { activeSenders--; }

    inline uint32
    getSendersCount() const
    { return activeSenders; }

protected:
    Members() :
        members(0),
        activeSenders(0)
    { }

    inline virtual ~Members()
    { }

private:
    /// number of identified members
    uint32 members;
    /// number of identified members that currently are active senders
    uint32 activeSenders;
};

/**
 * @class SyncSourceHandler
 * @short SyncSource objects modification methods.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
class __EXPORT SyncSourceHandler
{
public:
    /**
     * This requires SyncSource - SyncSourceHandler friendship.
     *
     * Get the SyncSourceLink corresponding to a SyncSource
     * object.
     **/
    inline void*
    getLink(const SyncSource& source) const
    { return source.getLink(); }

    inline void
    setLink(SyncSource& source, void* link)
    { source.setLink(link); }

    inline void
    setParticipant(SyncSource& source, Participant& p)
    { source.setParticipant(p); }

    inline void
    setState(SyncSource& source, SyncSource::State ns)
    { source.setState(ns); }

    inline void
    setSender(SyncSource& source, bool active)
    { source.setSender(active); }

    inline void
    setDataTransportPort(SyncSource& source, tpport_t p)
    { source.setDataTransportPort(p); }

    inline void
    setControlTransportPort(SyncSource& source, tpport_t p)
    { source.setControlTransportPort(p); }

    inline void
    setNetworkAddress(SyncSource& source, InetAddress addr)
    { source.setNetworkAddress(addr); }

protected:
    SyncSourceHandler()
    { }

    inline virtual ~SyncSourceHandler()
    { }
};

/**
 * @class ParticipantHandler
 * @short Participant objects modification methods.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
class __EXPORT ParticipantHandler
{
public:
    inline void
    setSDESItem(Participant* part, SDESItemType item,
            const std::string& val)
    { part->setSDESItem(item,val); }

    inline void
    setPRIVPrefix(Participant* part, const std::string val)
    { part->setPRIVPrefix(val); }

protected:
    ParticipantHandler()
    { }

    inline virtual ~ParticipantHandler()
    { }
};

/**
 * @class ApplicationHandler
 * @short Application objects modification methods.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
class __EXPORT ApplicationHandler
{
public:
    inline void
    addParticipant(RTPApplication& app, Participant& part)
    { app.addParticipant(part); }

    inline void
    removeParticipant(RTPApplication& app,
              RTPApplication::ParticipantLink* pl)
    { app.removeParticipant(pl); }

protected:
    ApplicationHandler()
    { }

    inline virtual ~ApplicationHandler()
    { }
};

/**
 * @class ConflictHandler
 * @short To track addresses of sources conflicting with the local
 * one.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
class __EXPORT ConflictHandler
{
public:
    struct ConflictingTransportAddress
    {
        ConflictingTransportAddress(InetAddress na,
                        tpport_t dtp, tpport_t ctp);

        void setNext(ConflictingTransportAddress* nc)
        { next = nc; }

        inline const InetAddress& getNetworkAddress( ) const
        { return networkAddress; }

        inline tpport_t getDataTransportPort() const
        { return dataTransportPort; }

        inline tpport_t getControlTransportPort() const
        { return controlTransportPort; }

        InetAddress networkAddress;
        tpport_t dataTransportPort;
        tpport_t controlTransportPort;
        ConflictingTransportAddress* next;
        // arrival time of last data or control packet.
        timeval lastPacketTime;
    };

    /**
     * @param na Inet network address.
     * @param dtp Data transport port.
     **/
    ConflictingTransportAddress* searchDataConflict(InetAddress na,
                            tpport_t dtp);
    /**
     * @param na Inet network address.
     * @param ctp Data transport port.
     **/
    ConflictingTransportAddress* searchControlConflict(InetAddress na,
                               tpport_t ctp);

    void updateConflict(ConflictingTransportAddress& ca)
    { SysTime::gettimeofday(&(ca.lastPacketTime),NULL); }

    void addConflict(const InetAddress& na, tpport_t dtp, tpport_t ctp);

protected:
    ConflictHandler()
    { firstConflict = lastConflict = NULL; }

    inline virtual ~ConflictHandler()
    { }

    ConflictingTransportAddress* firstConflict, * lastConflict;
};

/**
 * @class MembershipBookkeeping
 * @short Controls the group membership in the current session.
 *
 * For now, this class implements only a hash table of members, but
 * its design and relation with other classes is intented to support
 * group membership sampling in case scalability problems arise.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 */
class __EXPORT MembershipBookkeeping :
    public SyncSourceHandler,
    public ParticipantHandler,
    public ApplicationHandler,
    public ConflictHandler,
    private Members
{
public:
    inline size_t getDefaultMembersHashSize()
    { return defaultMembersHashSize; }

protected:

    /**
     * @short The initial size is a hint to allocate the resources
     * needed in order to keep the members' identifiers and
     * associated information.
     *
     * Although ccRTP will reallocate resources when it becomes
     * necessary, a good hint may save a lot of unpredictable time
     * penalties.
     *
     * @param initialSize an estimation of how many participants
     * the session will consist of.
     *
     */
    MembershipBookkeeping(uint32 initialSize = defaultMembersHashSize);

    /**
     * Purges all RTPSource structures created during the session,
     * as well as the hash table and the list of sources.
     **/
    inline virtual
    ~MembershipBookkeeping()
    { endMembers(); }

    struct SyncSourceLink;

    inline SyncSourceLink* getLink(const SyncSource& source) const
    { return static_cast<SyncSourceLink*>(SyncSourceHandler::getLink(source)); }
    /**
     * Get whether a synchronization source is recorded in this
     * membership controller.
     **/
    inline bool isMine(const SyncSource& source) const
    { return getLink(source)->getMembership() == this; }

    /**
     * @struct IncomingRTPPktLink
     *
     * @short Incoming RTP data packets control structure within
     * the incoming packet queue class.
     **/
    struct IncomingRTPPktLink
    {
        IncomingRTPPktLink(IncomingRTPPkt* pkt, SyncSourceLink* sLink,
                   struct timeval& recv_ts,
                   uint32 shifted_ts,
                   IncomingRTPPktLink* sp,
                   IncomingRTPPktLink* sn,
                   IncomingRTPPktLink* p,
                   IncomingRTPPktLink* n) :
            packet(pkt),
            sourceLink(sLink),
            prev(p), next(n),
            srcPrev(sp), srcNext(sn),
            receptionTime(recv_ts),
            shiftedTimestamp(shifted_ts)
        { }

        ~IncomingRTPPktLink()
        { }

        inline SyncSourceLink* getSourceLink() const
        { return sourceLink; }

        inline void setSourceLink(SyncSourceLink* src)
        { sourceLink = src; }

        inline IncomingRTPPktLink* getNext() const
        { return next; }

        inline void setNext(IncomingRTPPktLink* nl)
        { next = nl; }

        inline IncomingRTPPktLink* getPrev() const
        { return prev; }

        inline void setPrev(IncomingRTPPktLink* pl)
        { prev = pl; }

        inline IncomingRTPPktLink* getSrcNext() const
        { return srcNext; }

        inline void setSrcNext(IncomingRTPPktLink* sn)
        { srcNext = sn; }

        inline IncomingRTPPktLink* getSrcPrev() const
        { return srcPrev; }

        inline void setSrcPrev(IncomingRTPPktLink* sp)
        { srcPrev = sp; }

        inline IncomingRTPPkt* getPacket() const
        { return packet; }

        inline void setPacket(IncomingRTPPkt* pkt)
        { packet = pkt; }

        /**
         * Set the time this packet was received at.
         *
         * @param t time of reception.
         * @note this has almost nothing to do with the 32-bit
         * timestamp contained in the packet header.
         **/
        inline void setRecvTime(const timeval &t)
        { receptionTime = t; }

        /**
         * Get the time this packet was received at.
         **/
        inline timeval getRecvTime() const
        { return receptionTime; }

        /**
         * Get timestamp of this packet. The timestamp of
         * incoming packets is filtered so that the timestamp
         * this method provides for the first packet received
         * from every source starts from 0.
         *
         * @return 32 bit timestamp starting from 0 for each source.
         */
        inline uint32 getTimestamp() const
        { return shiftedTimestamp; }

        inline void setTimestamp(uint32 ts)
        { shiftedTimestamp = ts;}

        // the packet this link refers to.
        IncomingRTPPkt* packet;
        // the synchronization source this packet comes from.
        SyncSourceLink* sourceLink;
        // global incoming packet queue links.
        IncomingRTPPktLink* prev, * next;
        // source specific incoming packet queue links.
        IncomingRTPPktLink* srcPrev, * srcNext;
        // time this packet was received at
        struct timeval receptionTime;
        // timestamp of the packet in host order and after
        // substracting the initial timestamp for its source
        // (it is an increment from the initial timestamp).
        uint32 shiftedTimestamp;
    };

    /**
     * @struct SyncSourceLink
     *
     * @short Synchronization Source internal handler within the
     * incoming packets queue.
     *
     * Incoming packets queue objects hold a hash table and a
     * linked list of synchronization sources. For each of these
     * sources, there is also a linked list of incoming rtp
     * packets, which are linked in an "all incoming packets" list
     * as well. SyncSourceLink objects hold the necessary data to
     * maintain these data estructures, as well as source specific
     * information and statistics for RTCP,
     *
     * @author Federico Montesino Pouzols <fedemp@altern.org>
     **/
    struct SyncSourceLink
    {
        // 2^16
        static const uint32 SEQNUMMOD;

        SyncSourceLink(MembershipBookkeeping* m,
                   SyncSource* s,
                   IncomingRTPPktLink* fp = NULL,
                   IncomingRTPPktLink* lp = NULL,
                   SyncSourceLink* ps = NULL,
                   SyncSourceLink* ns = NULL,
                   SyncSourceLink* ncollis = NULL) :
            membership(m), source(s), first(fp), last(lp),
            prev(ps), next(ns), nextCollis(ncollis),
            prevConflict(NULL)
        { m->setLink(*s,this); // record that the source is associated
          initStats();         // to this link.
        }

        /**
         * Note it deletes the source.
         **/
        ~SyncSourceLink();

        inline MembershipBookkeeping* getMembership()
        { return membership; }

        /**
         * Get the synchronization source object this link
         * objet holds information for.
         **/
        inline SyncSource* getSource() { return source; }

        /**
         * Get first RTP (data) packet in the queue of packets
         * received from this socket.
         **/
        inline IncomingRTPPktLink* getFirst()
        { return first; }

        inline void setFirst(IncomingRTPPktLink* fp)
        { first = fp; }

        /**
         * Get last RTP (data) packet in the queue of packets
         * received from this socket.
         **/
        inline IncomingRTPPktLink* getLast()
        { return last; }

        inline void setLast(IncomingRTPPktLink* lp)
        { last = lp; }

        /**
         * Get the link object for the previous RTP source.
         **/
        inline SyncSourceLink* getPrev()
        { return prev; }

        inline void setPrev(SyncSourceLink* ps)
        { prev = ps; }

        /**
         * Get the link object for the next RTP source.
         **/
        inline SyncSourceLink* getNext()
        { return next; }

        inline void setNext(SyncSourceLink *ns)
        { next = ns; }

        /**
         * Get the link object for the next RTP source in the
         * hash table entry collision list.  Note that
         * collision does not refer to SSRC collision, but
         * hash table collision.
         **/
        inline SyncSourceLink* getNextCollis()
        { return nextCollis; }

        inline void setNextCollis(SyncSourceLink* ns)
        { nextCollis = ns; }

        inline ConflictingTransportAddress* getPrevConflict() const
        { return prevConflict; }

        /**
         * Get conflicting address.
         **/
        void setPrevConflict(InetAddress& addr, tpport_t dataPort,
                     tpport_t controlPort);

        unsigned char* getSenderInfo()
        { return senderInfo; }

        void setSenderInfo(unsigned char* si);

        unsigned char* getReceiverInfo()
        { return receiverInfo; }

        void setReceiverInfo(unsigned char* ri);

        inline timeval getLastPacketTime() const
        { return lastPacketTime; }

        inline timeval getLastRTCPPacketTime() const
        { return lastRTCPPacketTime; }

        inline timeval getLastRTCPSRTime() const
        { return lastRTCPSRTime; }

        /**
         * Get the total number of RTP packets received from this
         * source.
         */
        inline uint32 getObservedPacketCount() const
        { return obsPacketCount; }

        inline void incObservedPacketCount()
        { obsPacketCount++; }

        /**
         * Get the total number of payload octets received from this
         * source.
         **/
        inline uint32 getObservedOctetCount() const
        { return obsOctetCount; }

        inline void incObservedOctetCount(uint32 n)
        { obsOctetCount += n; }

        /**
         * Get the highest valid sequence number received.
         **/
        uint16
        getMaxSeqNum() const
        { return maxSeqNum; }

        /**
         * Set the highest valid sequence number recived.
         * @param max Sequence number.
         **/
        void
        setMaxSeqNum(uint16 max)
        { maxSeqNum = max; }

        inline uint32
        getExtendedMaxSeqNum() const
        { return extendedMaxSeqNum; }

        inline void
        setExtendedMaxSeqNum(uint32 seq)
        { extendedMaxSeqNum = seq; }

        inline uint32 getCumulativePacketLost() const
        { return cumulativePacketLost; }

        inline void setCumulativePacketLost(uint32 pl)
        { cumulativePacketLost = pl; }

        inline uint8 getFractionLost() const
        { return fractionLost; }

        inline void setFractionLost(uint8 fl)
        { fractionLost = fl; }

        inline uint32 getLastPacketTransitTime()
        { return lastPacketTransitTime; }

        inline void setLastPacketTransitTime(uint32 time)
        { lastPacketTransitTime = time; }

        inline float getJitter() const
        { return jitter; }

        inline void setJitter(float j)
        { jitter = j; }

        inline uint32 getInitialDataTimestamp() const
        { return initialDataTimestamp; }

        inline void setInitialDataTimestamp(uint32 ts)
        { initialDataTimestamp = ts; }

        inline timeval getInitialDataTime() const
        { return initialDataTime; }

        inline void setInitialDataTime(timeval it)
        { initialDataTime = it; }

        /**
         * Mark this source as having sent a BYE control packet.
         *
         * @return whether some packet from this source had
         * been received before (getHello() has been called at
         * least once)
         **/
        bool getGoodbye()
        {
            if(!flag)
                return false;
            flag = false;
            return true;
        }

        /**
         * Mark this source as having sent some packet.
         *
         * @return whether no packet from this source had been
         * received before
         **/
        bool getHello() {
            if(flag)
                return false;
            flag = true;
            return true;
        }

        inline uint32 getBadSeqNum() const
        { return badSeqNum; }

        inline void setBadSeqNum(uint32 seq)
        { badSeqNum = seq; }

        uint8 getProbation() const
        { return probation; }

        inline void setProbation(uint8 p)
        { probation = p; }

        inline void decProbation()
        { --probation; }

        bool isValid() const
        { return 0 == probation; }

        inline uint16 getBaseSeqNum() const
        { return baseSeqNum; }

        inline void setBaseSeqNum(uint16 seqnum)
        { baseSeqNum = seqnum; }

        inline uint32 getSeqNumAccum() const
        { return seqNumAccum; }

        inline void incSeqNumAccum()
        { seqNumAccum += SEQNUMMOD; }

        /**
         * Start a new sequence of received packets.
         **/
        inline void initSequence(uint16 seqnum)
        { maxSeqNum = seqNumAccum = seqnum; }

        /**
         * Record the insertion of an RTP packet from this
         * source into the scheduled reception queue. All
         * received packets should be registered with
         * recordReception(), but only those actually inserted
         * into the queue should be registered via this
         * method.
         *
         * @param pl Link structure for packet inserted into the queue.
         **/
        void recordInsertion(const IncomingRTPPktLink& pl);

        void initStats();

        /**
         * Compute cumulative packet lost and fraction of
         * packets lost during the last reporting interval.
         **/
        void computeStats();

        MembershipBookkeeping* membership;
        // The source this link object refers to.
        SyncSource* source;
        // first/last packets from this source in the queue.
        IncomingRTPPktLink* first, * last;
        // Links for synchronization sources located before
        // and after this one in the list of sources.
        SyncSourceLink* prev, * next;
        // Prev and next inside the hash table collision list.
        SyncSourceLink* nextCollis;
        ConflictingTransportAddress* prevConflict;
        unsigned char* senderInfo;
        unsigned char* receiverInfo;
        // time the last RTP packet from this source was
        // received at.
        timeval lastPacketTime;
        // time the last RTCP packet was received.
        timeval lastRTCPPacketTime;
        // time the lasrt RTCP SR was received. Required for
        // DLSR computation.
        timeval lastRTCPSRTime;

        // for outgoing RR reports.
        // number of packets received from this source.
        uint32 obsPacketCount;
        // number of octets received from this source.
        uint32 obsOctetCount;
        // the higher sequence number seen from this source
        uint16 maxSeqNum;
        uint32 extendedMaxSeqNum;
        uint32 cumulativePacketLost;
        uint8 fractionLost;
        // for interarrivel jitter computation
        uint32 lastPacketTransitTime;
        // interarrival jitter of packets from this source.
        float jitter;
        uint32 initialDataTimestamp;
        timeval initialDataTime;

        // this flag assures we only call one gotHello and one
        // gotGoodbye for this src.
        bool flag;

        // for source validation:
        uint32 badSeqNum;
        uint8 probation;  // packets in sequence before valid.
        uint16 baseSeqNum;
        uint32 expectedPrior;
        uint32 receivedPrior;
        uint32 seqNumAccum;
    };

    /**
     * Returns whether there is already a synchronizacion source
     * with "ssrc" SSRC identifier.
     **/
    bool
    isRegistered(uint32 ssrc);

    /**
     * Get the description of a source by its <code>ssrc</code> identifier.
     *
     * @param ssrc SSRC identifier, in host order.
     * @param created whether a new source has been created.
     * @return Pointer to the SyncSource object identified by
     * <code>ssrc</code>.
     */
    SyncSourceLink*
    getSourceBySSRC(uint32 ssrc, bool& created);

    /**
     * Mark the source identified by <code>ssrc</code> as having
     * sent a BYE packet. It is not deleted until a timeout
     * expires, so that in case some packets from this source
     * arrive a bit later the source is not inserted again in the
     * table of known sources.
     *
     * @return true if the source had been previously identified.
     * false if it was not in the table of known sources.
     **/
    bool
    BYESource(uint32 ssrc);

    /**
     * Remove the description of the source identified by
     * <code>ssrc</code>
     *
     * @return whether the source has been actually removed or it
     * did not exist.
     */
    bool
    removeSource(uint32 ssrc);

    inline SyncSourceLink* getFirst()
    { return first; }

    inline SyncSourceLink* getLast()
    { return last; }

    inline uint32
    getMembersCount()
    { return Members::getMembersCount(); }

    inline void
    setMembersCount(uint32 n)
    { Members::setMembersCount(n); }

    inline uint32
    getSendersCount()
    { return Members::getSendersCount(); }

    static const size_t defaultMembersHashSize;
    static const uint32 SEQNUMMOD;

private:
    MembershipBookkeeping(const MembershipBookkeeping &o);

    MembershipBookkeeping&
    operator=(const MembershipBookkeeping &o);

    /**
     * Purge all RTPSource structures, the hash table and the list
     * of sources.
     **/
    void
    endMembers();

    // Hash table with sources of RTP and RTCP packets
    uint32 sourceBucketsNum;
    SyncSourceLink** sourceLinks;
    // List of sources, ordered from older to newer
    SyncSourceLink* first, * last;
};

/**
 * @class IncomingDataQueue
 * @short Queue for incoming RTP data packets in an RTP session.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
class __EXPORT IncomingDataQueue: public IncomingDataQueueBase,
    protected MembershipBookkeeping
{
public:
    /**
     * @class SyncSourcesIterator
     * @short iterator through the list of synchronizations
     * sources in this session
     **/
    class SyncSourcesIterator
    {
    public:
        typedef std::forward_iterator_tag iterator_category;
        typedef SyncSource value_type;
        typedef std::ptrdiff_t difference_type;
        typedef const SyncSource* pointer;
        typedef const SyncSource& reference;

        SyncSourcesIterator(SyncSourceLink* l = NULL) :
            link(l)
        { }

        SyncSourcesIterator(const SyncSourcesIterator& si) :
            link(si.link)
        { }

        reference operator*() const
        { return *(link->getSource()); }

        pointer operator->() const
        { return link->getSource(); }

        SyncSourcesIterator& operator++() {
            link = link->getNext();
            return *this;
        }

        SyncSourcesIterator operator++(int) {
            SyncSourcesIterator result(*this);
            ++(*this);
            return result;
        }

        friend bool operator==(const SyncSourcesIterator& l,
                       const SyncSourcesIterator& r)
        { return l.link == r.link; }

        friend bool operator!=(const SyncSourcesIterator& l,
                       const SyncSourcesIterator& r)
        { return l.link != r.link; }

    private:
        SyncSourceLink *link;
    };

    SyncSourcesIterator begin()
    { return SyncSourcesIterator(MembershipBookkeeping::getFirst()); }

    SyncSourcesIterator end()
    { return SyncSourcesIterator(NULL); }

    /**
     * Retreive data from a specific timestamped packet if such a
     * packet is currently available in the receive buffer.
     *
     * @param stamp Data unit timestamp.
     * @param src Optional synchronization source selector.
     * @return data retrieved from the reception buffer.
     * @retval null pointer if no packet with such timestamp is available.
     **/
    const AppDataUnit*
    getData(uint32 stamp, const SyncSource* src = NULL);


    /**
     * Determine if packets are waiting in the reception queue.
     *
     * @param src Optional synchronization source selector.
     * @return True if packets are waiting.
     */
    bool
    isWaiting(const SyncSource* src = NULL) const;

    /**
     * Get timestamp of first packet waiting in the queue.
     *
     * @param src optional source selector.
     * @return timestamp of first arrival packet.
     **/
    uint32
    getFirstTimestamp(const SyncSource* src = NULL) const;

    /**
     * When receiving packets from a new source, it may be
     * convenient to reject a first few packets before we are
     * really sure the source is valid. This method sets how many
     * data packets must be received in sequence before the source
     * is considered valid and the stack starts to accept its
     * packets.
     *
     * @note the default (see defaultMinValidPacketSequence())
     * value for this parameter is 0, so that no packets are
     * rejected (data packets are accepted from the first one).
     *
     * @note this validation is performed after the generic header
     * validation and the additional validation done in
     * onRTPPacketRecv().
     *
     * @note if any valid RTCP packet is received from this
     * source, it will be immediatly considered valid regardless
     * of the number of sequential data packets received.
     *
     * @param packets number of sequential packet required
     **/
    void
    setMinValidPacketSequence(uint8 packets)
    { minValidPacketSequence = packets; }

    uint8
    getDefaultMinValidPacketSequence() const
    { return defaultMinValidPacketSequence; }

    /**
     * Get the minimun number of consecutive packets that must be
     * received from a source before accepting its data packets.
     **/
    uint8
    getMinValidPacketSequence() const
    { return minValidPacketSequence; }

    void
    setMaxPacketMisorder(uint16 packets)
    { maxPacketMisorder = packets; }

    uint16
    getDefaultMaxPacketMisorder() const
    { return defaultMaxPacketMisorder; }

    uint16
    getMaxPacketMisorder() const
    { return maxPacketMisorder; }

    /**
     *
     * It also prevents packets sent after a restart of the source
     * being immediately accepted.
     **/
    void
    setMaxPacketDropout(uint16 packets) // default: 3000.
    { maxPacketDropout = packets; }

    uint16
    getDefaultMaxPacketDropout() const
    { return defaultMaxPacketDropout; }

    uint16
    getMaxPacketDropout() const
    { return maxPacketDropout; }

    // default value for constructors that allow to specify
    // members table s\ize
        inline static size_t
        getDefaultMembersSize()
        { return defaultMembersSize; }

        /**
         * Set input queue CryptoContext.
         *
         * The endQueue method (provided by RTPQueue) deletes all
         * registered CryptoContexts.
         *
         * @param cc Pointer to initialized CryptoContext.
         */
        void
        setInQueueCryptoContext(CryptoContext* cc);

        /**
         * Remove input queue CryptoContext.
         *
         * The endQueue method (provided by RTPQueue) also deletes all
         * registered CryptoContexts.
         *
         * @param cc
         *     Pointer to initialized CryptoContext to remove. If pointer
         *     if <code>NULL</code> then delete the whole queue
         */
        void
        removeInQueueCryptoContext(CryptoContext* cc);

        /**
         * Get an input queue CryptoContext identified by SSRC
         *
         * @param ssrc Request CryptoContext for this incoming SSRC
         * @return Pointer to CryptoContext of the SSRC of NULL if no context
         * available for this SSRC.
         */
        CryptoContext*
        getInQueueCryptoContext(uint32 ssrc);

protected:
    /**
     * @param size initial size of the membership table.
     **/
    IncomingDataQueue(uint32 size);

    virtual ~IncomingDataQueue()
    { }

    /**
     * Apply collision and loop detection and correction algorithm
     * when receiving RTP data packets. Follows section 8.2 in
     * draft-ietf-avt-rtp-new.
     *
     * @param sourceLink link to the source object.
     * @param is_new whether the source has been just recorded.
     * @param na data packet network address.
     * @param tp data packet source transport port.
     *
     * @return whether the packet must not be discarded.
     **/
    bool checkSSRCInIncomingRTPPkt(SyncSourceLink& sourceLink,
                       bool is_new, InetAddress& na,
                       tpport_t tp);

    /**
     * Set the number of RTCP intervals that the stack will wait
     * to change the state of a source from stateActive to
     * stateInactive, or to delete the source after being in
     * stateInactive.
     *
     * Note that this value should be uniform accross all
     * participants and SHOULD be fixed for a particular profile.
     *
     * @param intervals number of RTCP report intervals
     *
     * @note If RTCP is not being used, the RTCP interval is
     * assumed to be the default: 5 seconds.
     * @note The default for this value is, as RECOMMENDED, 5.
     **/
    void setSourceExpirationPeriod(uint8 intervals)
    { sourceExpirationPeriod = intervals; }

    /**
     * This function is used by the service thread to process
     * the next incoming packet and place it in the receive list.
     *
     * @return number of payload bytes received.  <0 if error.
     */
    virtual size_t
    takeInDataPacket();

    void renewLocalSSRC();

    /**
     * This is used to fetch a packet in the receive queue and to
     * expire packets older than the current timestamp.
     *
     * @return packet buffer object for current timestamp if found.
     * @param timestamp timestamp requested.
     * @param src optional source selector
     * @note if found, the packet is removed from the reception queue
     **/
    IncomingDataQueue::IncomingRTPPktLink*
    getWaiting(uint32 timestamp, const SyncSource *src = NULL);

    /**
     * Log reception of a new RTP packet from this source. Usually
     * updates data such as the packet counter, the expected
     * sequence number for the next packet and the time the last
     * packet was received at.
     *
     * @param srcLink Link structure for the synchronization
     * source of this packet.
     * @param pkt Packet just created and to be logged.
     * @param recvtime Reception time.
     *
     * @return whether, according to the source state and
     * statistics, the packet is considered valid and must be
     * inserted in the incoming packets queue.
     **/
    bool
    recordReception(SyncSourceLink& srcLink, const IncomingRTPPkt& pkt,
            const timeval recvtime);

    /**
     * Log extraction of a packet from this source from the
     * scheduled reception queue.
     *
     * @param pkt Packet extracted from the queue.
     **/
    void
    recordExtraction(const IncomingRTPPkt& pkt);

    void purgeIncomingQueue();

    /**
     * Virtual called when a new synchronization source has joined
     * the session.
     *
     * @param - new synchronization source
     **/
    inline virtual void
    onNewSyncSource(const SyncSource&)
    { }

protected:
    /**
     * A virtual function to support parsing of arriving packets
     * to determine if they should be kept in the queue and to
     * dispatch events.
     *
     * A generic header validity check (as specified in RFC 1889)
     * is performed on every incoming packet. If the generic check
     * completes successfully, this method is called before the
     * packet is actually inserted into the reception queue.
     *
     * May be used to perform additional validity checks or to do
     * some application specific processing.
     *
     * @param - packet just received.
     * @return true if packet is kept in the incoming packets queue.
     **/
    inline virtual bool
    onRTPPacketRecv(IncomingRTPPkt&)
    { return true; }

    /**
     * A hook to filter packets in the receive queue that are being
     * expired. This hook may be used to do some application
     * specific processing on expired packets before they are
     * deleted.
     *
     * @param - packet expired from the recv queue.
     **/
    inline virtual void onExpireRecv(IncomingRTPPkt&)
    { return; }

        /**
         * A hook that gets called if the decoding of an incoming SRTP was erroneous
         *
         * @param pkt
         *     The SRTP packet with error.
         * @param errorCode
         *     The error code: -1 - SRTP authentication failure, -2 - replay
         *     check failed
         * @return
         *     True: put the packet in incoming queue for further processing
         *     by the applications; false: dismiss packet. The default
         *     implementation returns false.
         **/
        inline virtual bool
        onSRTPPacketError(IncomingRTPPkt& pkt, int32 errorCode)
        { return false; }

        inline virtual bool
    end2EndDelayed(IncomingRTPPktLink&)
    { return false; }

        /**
     * Insert a just received packet in the queue (both general
     * and source specific queues). If the packet was already in
     * the queue (same SSRC and sequence number), it is not
     * inserted but deleted.
     *
     * @param packetLink link to a packet just received and
     * generally validated and processed by onRTPPacketRecv.
     *
     * @return whether the packet was successfully inserted.
     * @retval false when the packet is duplicated (there is
     * already a packet from the same source with the same
     * timestamp).
     * @retval true when the packet is not duplicated.
     **/
    bool
    insertRecvPacket(IncomingRTPPktLink* packetLink);

    /**
     * This function performs the physical I/O for reading a
     * packet from the source.  It is a virtual that is
     * overridden in the derived class.
     *
     * @return number of bytes read.
     * @param buffer of read packet.
     * @param length of data to read.
     * @param host address of source.
     * @param port number of source.
     **/
    virtual size_t
    recvData(unsigned char* buffer, size_t length,
         InetHostAddress& host, tpport_t& port) = 0;

    virtual size_t
    getNextDataPacketSize() const = 0;

    mutable ThreadLock recvLock;
    // reception queue
    IncomingRTPPktLink* recvFirst, * recvLast;
    // values for packet validation.
    static const uint8 defaultMinValidPacketSequence;
    static const uint16 defaultMaxPacketMisorder;
    static const uint16 defaultMaxPacketDropout;
    uint8 minValidPacketSequence;
    uint16 maxPacketMisorder;
    uint16 maxPacketDropout;
    static const size_t defaultMembersSize;
    uint8 sourceExpirationPeriod;
    mutable Mutex cryptoMutex;
        std::list<CryptoContext *> cryptoContexts;
};

/** @}*/ // iqueue

END_NAMESPACE

#endif  //CCXX_RTP_IQUEUE_H_

/** EMACS **
 * Local variables:
 * mode: c++
 * c-basic-offset: 8
 * End:
 */