00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00050 #include "private.h"
00051 #include <ccrtp/cqueue.h>
00052
00053 #ifdef CCXX_NAMESPACES
00054 namespace ost {
00055 #endif
00056
00057 const uint32 MembershipBookkeeping::SyncSourceLink::SEQNUMMOD = (1<<16);
00058
00059 MembershipBookkeeping::SyncSourceLink::~SyncSourceLink()
00060 {
00061 #ifdef CCXX_EXCEPTIONS
00062 try {
00063 #endif
00064 delete source;
00065 delete prevConflict;
00066 delete receiverInfo;
00067 delete senderInfo;
00068 #ifdef CCXX_EXCEPTIONS
00069 } catch (...) { }
00070 #endif
00071 }
00072
00073 void
00074 MembershipBookkeeping::SyncSourceLink::initStats()
00075 {
00076 lastPacketTime.tv_sec = lastPacketTime.tv_usec = 0;
00077 lastRTCPPacketTime.tv_sec = lastRTCPPacketTime.tv_usec = 0;
00078 lastRTCPSRTime.tv_sec = lastRTCPSRTime.tv_usec = 0;
00079
00080 senderInfo = NULL;
00081 receiverInfo = NULL;
00082
00083 obsPacketCount = obsOctetCount = 0;
00084 maxSeqNum = extendedMaxSeqNum = 0;
00085 cumulativePacketLost = 0;
00086 fractionLost = 0;
00087 jitter = 0;
00088 initialDataTimestamp = 0;
00089 initialDataTime.tv_sec = initialDataTime.tv_usec = 0;
00090 flag = false;
00091
00092 badSeqNum = SEQNUMMOD + 1;
00093 probation = 0;
00094 baseSeqNum = 0;
00095 expectedPrior = 0;
00096 receivedPrior = 0;
00097 seqNumAccum = 0;
00098 }
00099
00100 void
00101 MembershipBookkeeping::SyncSourceLink::computeStats()
00102 {
00103
00104
00105
00106 setExtendedMaxSeqNum(getMaxSeqNum() + getSeqNumAccum());
00107 uint32 expected =
00108 (getExtendedMaxSeqNum() - getBaseSeqNum() + 1);
00109 uint32 pc = getObservedPacketCount();
00110 uint32 lost;
00111 if ( 0 == pc )
00112 lost = 0;
00113 else
00114 lost = expected - pc;
00115 setCumulativePacketLost(lost);
00116
00117
00118
00119 uint32 expectedDelta = expected - expectedPrior;
00120 expectedPrior = expected;
00121 uint32 receivedDelta = getObservedPacketCount() -
00122 receivedPrior;
00123 receivedPrior = getObservedPacketCount();
00124 uint32 lostDelta = expectedDelta - receivedDelta;
00125 if ( expectedDelta == 0 || lostDelta <= 0 )
00126 setFractionLost(0);
00127 else
00128 setFractionLost((lostDelta<<8) / expectedDelta );
00129 }
00130
00131 void
00132 MembershipBookkeeping::SyncSourceLink::setPrevConflict(InetAddress& addr,
00133 tpport_t dataPort,
00134 tpport_t controlPort)
00135 {
00136 delete prevConflict;
00137 prevConflict =
00138 new ConflictingTransportAddress(addr,dataPort,controlPort);
00139 }
00140
00141 void
00142 MembershipBookkeeping::SyncSourceLink::
00143 recordInsertion(const IncomingRTPPktLink&)
00144 {
00145 }
00146
00147 void
00148 MembershipBookkeeping::SyncSourceLink::
00149 setSenderInfo(unsigned char* si)
00150 {
00151 if ( NULL == senderInfo )
00152 senderInfo = reinterpret_cast<unsigned char*>
00153 (new RTCPCompoundHandler::SenderInfo);
00154 memcpy(senderInfo,si,sizeof(RTCPCompoundHandler::SenderInfo));
00155 }
00156
00157 void
00158 MembershipBookkeeping::SyncSourceLink::
00159 setReceiverInfo(unsigned char* ri)
00160 {
00161 if ( NULL == receiverInfo )
00162 receiverInfo = reinterpret_cast<unsigned char*>
00163 (new RTCPCompoundHandler::ReceiverInfo);
00164 memcpy(receiverInfo,ri,sizeof(RTCPCompoundHandler::ReceiverInfo));
00165 }
00166
00167 const size_t MembershipBookkeeping::defaultMembersHashSize = 11;
00168 const uint32 MembershipBookkeeping::SEQNUMMOD = (1<<16);
00169
00170 #define HASH(a) ((a + (a >> 8)) % MembershipBookkeeping::sourceBucketsNum)
00171
00172
00173
00174 MembershipBookkeeping::MembershipBookkeeping(uint32 initialSize):
00175 SyncSourceHandler(), ParticipantHandler(),
00176 ConflictHandler(), Members(),
00177 sourceBucketsNum(initialSize),
00178 sourceLinks( new SyncSourceLink* [sourceBucketsNum] ),
00179 first(NULL), last(NULL)
00180 {
00181 for ( uint32 i = 0; i < sourceBucketsNum; i++ )
00182 sourceLinks[i] = NULL;
00183 }
00184
00185 void
00186 MembershipBookkeeping::endMembers()
00187 {
00188 SyncSourceLink* s;
00189 while( first ) {
00190 s = first;
00191 first = first->next;
00192 #ifdef CCXX_EXCEPTIONS
00193 try {
00194 #endif
00195 delete s;
00196 #ifdef CCXX_EXCEPTIONS
00197 } catch (...) {}
00198 #endif
00199 }
00200 last = NULL;
00201 #ifdef CCXX_EXCEPTIONS
00202 try {
00203 #endif
00204 delete [] sourceLinks;
00205 #ifdef CCXX_EXCEPTIONS
00206 } catch (...) {}
00207 #endif
00208 }
00209
00210 bool
00211 MembershipBookkeeping::isRegistered(uint32 ssrc)
00212 {
00213 bool result = false;
00214 SyncSourceLink* sl = sourceLinks[ HASH(ssrc) ];
00215
00216 while ( sl != NULL ) {
00217 if ( ssrc == sl->getSource()->getID() ) {
00218 result = true;
00219 break;
00220 } else if ( ssrc < sl->getSource()->getID() ) {
00221 break;
00222 } else {
00223
00224 sl = sl->getNextCollis();
00225 }
00226 }
00227 return result;
00228 }
00229
00230
00231 MembershipBookkeeping::SyncSourceLink*
00232 MembershipBookkeeping::getSourceBySSRC(uint32 ssrc, bool& created)
00233 {
00234 uint32 hashing = HASH(ssrc);
00235 SyncSourceLink* result = sourceLinks[hashing];
00236 SyncSourceLink* prev = NULL;
00237 created = false;
00238
00239 if ( NULL == result ) {
00240 result = sourceLinks[hashing] =
00241 new SyncSourceLink(this,new SyncSource(ssrc));
00242 created = true;
00243 } else {
00244 while ( NULL != result ) {
00245 if ( ssrc == result->getSource()->getID() ) {
00246
00247 break;
00248 } else if ( ssrc > result->getSource()->getID() ) {
00249
00250 prev = result;
00251 result = result->getNextCollis();
00252 } else {
00253
00254
00255 SyncSourceLink* newlink =
00256 new SyncSourceLink(this,new SyncSource(ssrc));
00257 if ( NULL != prev )
00258 prev->setNextCollis(newlink);
00259 else
00260 sourceLinks[hashing] = newlink;
00261 newlink->setNextCollis(result);
00262 result = newlink;
00263 created = true;
00264 break;
00265 }
00266 }
00267 if ( NULL == result ) {
00268
00269 result =
00270 new SyncSourceLink(this,new SyncSource(ssrc));
00271 created = true;
00272 prev->setNextCollis(result);
00273 }
00274 }
00275 if ( created ) {
00276 if ( first )
00277 last->setNext(result);
00278 else
00279 first = result;
00280 last = result;
00281 increaseMembersCount();
00282 }
00283
00284 return result;
00285 }
00286
00287 bool
00288 MembershipBookkeeping::BYESource(uint32 ssrc)
00289 {
00290 bool found = false;
00291
00292
00293 if ( isRegistered(ssrc) ) {
00294 found = true;
00295 decreaseMembersCount();
00296 }
00297 return found;
00298 }
00299
00300 bool
00301 MembershipBookkeeping::removeSource(uint32 ssrc)
00302 {
00303 bool found = false;
00304 SyncSourceLink* old = NULL,
00305 * s = sourceLinks[ HASH(ssrc) ];
00306 while ( s != NULL ){
00307 if ( s->getSource()->getID() == ssrc ) {
00308
00309 if ( old )
00310 old->setNextCollis(s->getNextCollis());
00311 if ( s->getPrev() )
00312 s->getPrev()->setNext(s->getNext());
00313 if ( s->getNext() )
00314 s->getNext()->setPrev(s->getPrev());
00315 decreaseMembersCount();
00316 if ( s->getSource()->isSender() )
00317 decreaseSendersCount();
00318 delete s;
00319 found = true;
00320 break;
00321 } else if ( s->getSource()->getID() > ssrc ) {
00322
00323 break;
00324 } else {
00325
00326 old = s;
00327 s = s->getNextCollis();
00328 }
00329 }
00330 return found;
00331 }
00332
00333 #ifdef CCXX_NAMESPACES
00334 }
00335 #endif
00336