Main Page | Modules | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

members.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2001,2002 Federico Montesino <p5087@quintero.fie.us.es>
00002 //  
00003 // This program is free software; you can redistribute it and/or modify
00004 // it under the terms of the GNU General Public License as published by
00005 // the Free Software Foundation; either version 2 of the License, or
00006 // (at your option) any later version.
00007 // 
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 // 
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software 
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00016 // 
00017 // As a special exception, you may use this file as part of a free software
00018 // library without restriction.  Specifically, if other files instantiate
00019 // templates or use macros or inline functions from this file, or you compile
00020 // this file and link it with other files to produce an executable, this
00021 // file does not by itself cause the resulting executable to be covered by
00022 // the GNU General Public License.  This exception does not however    
00023 // invalidate any other reasons why the executable file might be covered by
00024 // the GNU General Public License.    
00025 //
00026 // This exception applies only to the code released under the name GNU
00027 // ccRTP.  If you copy code from other releases into a copy of GNU
00028 // ccRTP, as the General Public License permits, the exception does
00029 // not apply to the code that you add in this way.  To avoid misleading
00030 // anyone as to the status of such modified files, you must delete
00031 // this exception notice from them.
00032 //
00033 // If you write modifications of your own for GNU ccRTP, it is your choice
00034 // whether to permit this exception to apply to your modifications.
00035 // If you do not wish that, delete this exception notice.
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         // See Appendix A.3
00104         
00105         // compute cumulative packet lost.
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         // compute the fraction of packets lost during the last
00118         // reporting interval.
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 // Initializes the array (hash table) and the global list of
00173 // SyncSourceLink objects
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                         // keep on searching
00224                         sl = sl->getNextCollis();
00225                 }
00226         }
00227         return result;
00228 }
00229 
00230 // Gets or creates the source and its link structure.
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                                 // we found it!
00247                                 break;
00248                         } else if ( ssrc > result->getSource()->getID() ) {
00249                                 // keep on searching
00250                                 prev = result;
00251                                 result = result->getNextCollis();
00252                         } else { 
00253                                 // ( ssrc < result->getSource()->getID() )
00254                                 // it isn't recorded here -> create it.
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                         // insert at the end of the collision list
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         // If the source identified by ssrc is in the table, mark it
00292         // as leaving the session. If it was not, do nothing.
00293         if ( isRegistered(ssrc) ) {
00294                 found = true;
00295                 decreaseMembersCount(); // TODO really decrease right now?
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                         // we found it
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                         // it wasn't here
00323                         break;
00324                 } else {
00325                         // keep on searching
00326                         old = s;
00327                         s = s->getNextCollis();
00328                 }
00329         }
00330         return found;
00331 }
00332 
00333 #ifdef  CCXX_NAMESPACES
00334 }
00335 #endif
00336 

© sourcejam.com 2005-2008