/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
**********/
// "liveMedia"
// Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
// RTCP
// Implementation

#include "RTCP.hh"
#include "GroupsockHelper.hh"
#include "rtcp_from_spec.h"
#if defined(__WIN32__) || defined(_WIN32) || defined(_QNX4)
#define snprintf _snprintf
#endif

////////// RTCPMemberDatabase //////////

class RTCPMemberDatabase {
public:
  RTCPMemberDatabase(RTCPInstance& ourRTCPInstance)
    : fOurRTCPInstance(ourRTCPInstance), fNumMembers(1 /*ourself*/),
      fTable(HashTable::create(ONE_WORD_HASH_KEYS)) {
  }

  virtual ~RTCPMemberDatabase() {
	delete fTable;
  }

  Boolean isMember(u_int32_t ssrc) const {
    return fTable->Lookup((char*)(long)ssrc) != NULL;
  }

  Boolean noteMembership(u_int32_t ssrc, unsigned curTimeCount) {
    Boolean isNew = !isMember(ssrc);

    if (isNew) {
      ++fNumMembers;
    }

    // Record the current time, so we can age stale members
    fTable->Add((char*)(long)ssrc, (void*)(long)curTimeCount);

    return isNew;
  }

  Boolean remove(u_int32_t ssrc) {
    Boolean wasPresent = fTable->Remove((char*)(long)ssrc);
    if (wasPresent) {
      --fNumMembers;
    }
    return wasPresent;
  }

  unsigned numMembers() const {
    return fNumMembers;
  }

  void reapOldMembers(unsigned threshold);

private:
  RTCPInstance& fOurRTCPInstance;
  unsigned fNumMembers;
  HashTable* fTable;
};

void RTCPMemberDatabase::reapOldMembers(unsigned threshold) {
  Boolean foundOldMember;
  u_int32_t oldSSRC = 0;

  do {
    foundOldMember = False;

    HashTable::Iterator* iter
      = HashTable::Iterator::create(*fTable);
    uintptr_t timeCount;
    char const* key;
    while ((timeCount = (uintptr_t)(iter->next(key))) != 0) {
#ifdef DEBUG
      fprintf(stderr, "reap: checking SSRC 0x%lx: %ld (threshold %d)\n", (unsigned long)key, timeCount, threshold);
#endif
      if (timeCount < (uintptr_t)threshold) { // this SSRC is old
        uintptr_t ssrc = (uintptr_t)key;
        oldSSRC = (u_int32_t)ssrc;
        foundOldMember = True;
      }
    }
    delete iter;

    if (foundOldMember) {
#ifdef DEBUG
        fprintf(stderr, "reap: removing SSRC 0x%x\n", oldSSRC);
#endif
	fOurRTCPInstance.removeSSRC(oldSSRC, True);
    }
  } while (foundOldMember);
}


////////// RTCPInstance //////////

static double dTimeNow() {
    struct timeval timeNow;
    gettimeofday(&timeNow, NULL);
    return (double) (timeNow.tv_sec + timeNow.tv_usec/1000000.0);
}

static unsigned const maxRTCPPacketSize = 1438;
	// bytes (1500, minus some allowance for IP, UDP, UMTP headers; SRTCP trailers)
static unsigned const preferredRTCPPacketSize = 1000; // bytes

RTCPInstance::RTCPInstance(UsageEnvironment& env, Groupsock* RTCPgs,
			   unsigned totSessionBW,
			   unsigned char const* cname,
			   RTPSink* sink, RTPSource* source,
			   Boolean isSSMTransmitter,
			   SRTPCryptographicContext* crypto)
  : Medium(env), fRTCPInterface(this, RTCPgs), fTotSessionBW(totSessionBW),
    fSink(sink), fSource(source), fIsSSMTransmitter(isSSMTransmitter), fCrypto(crypto),
    fCNAME(RTCP_SDES_CNAME, cname), fOutgoingReportCount(1),
    fAveRTCPSize(0), fIsInitial(1), fPrevNumMembers(0),
    fLastSentSize(0), fLastReceivedSize(0), fLastReceivedSSRC(0),
    fTypeOfEvent(EVENT_UNKNOWN), fTypeOfPacket(PACKET_UNKNOWN_TYPE),
    fHaveJustSentPacket(False), fLastPacketSentSize(0),
    fByeHandlerTask(NULL), fByeWithReasonHandlerTask(NULL), fByeHandlerClientData(NULL),
    fSRHandlerTask(NULL), fSRHandlerClientData(NULL),
    fRRHandlerTask(NULL), fRRHandlerClientData(NULL),
    fSpecificRRHandlerTable(NULL),
    fAppHandlerTask(NULL), fAppHandlerClientData(NULL) {
#ifdef DEBUG
  fprintf(stderr, "RTCPInstance[%p]::RTCPInstance()\n", this);
#endif
  if (fTotSessionBW == 0) { // not allowed!
    env << "RTCPInstance::RTCPInstance error: totSessionBW parameter should not be zero!\n";
    fTotSessionBW = 1;
  }

  if (isSSMTransmitter) RTCPgs->multicastSendOnly(); // don't receive multicast

  double timeNow = dTimeNow();
  fPrevReportTime = fNextReportTime = timeNow;

  fKnownMembers = new RTCPMemberDatabase(*this);
  fInBuf = new unsigned char[maxRTCPPacketSize];
  if (fKnownMembers == NULL || fInBuf == NULL) return;
  fNumBytesAlreadyRead = 0;

  fOutBuf = new OutPacketBuffer(preferredRTCPPacketSize, maxRTCPPacketSize, 1500);
  if (fOutBuf == NULL) return;

  if (fSource != NULL && fSource->RTPgs() == RTCPgs) {
    // We're receiving RTCP reports that are multiplexed with RTP, so ask the RTP source
    // to give them to us:
    fSource->registerForMultiplexedRTCPPackets(this);
  } else {
    // Arrange to handle incoming reports from the network:
    TaskScheduler::BackgroundHandlerProc* handler
      = (TaskScheduler::BackgroundHandlerProc*)&incomingReportHandler;
    fRTCPInterface.startNetworkReading(handler);
  }

  // Send our first report.
  fTypeOfEvent = EVENT_REPORT;
  onExpire(this);
}

struct RRHandlerRecord {
  TaskFunc* rrHandlerTask;
  void* rrHandlerClientData;
};

RTCPInstance::~RTCPInstance() {
#ifdef DEBUG
  fprintf(stderr, "RTCPInstance[%p]::~RTCPInstance()\n", this);
#endif
  // Begin by sending a BYE.  We have to do this immediately, without
  // 'reconsideration', because "this" is going away.
  fTypeOfEvent = EVENT_BYE; // not used, but...
  sendBYE();

  if (fSource != NULL && fSource->RTPgs() == fRTCPInterface.gs()) {
    // We were receiving RTCP reports that were multiplexed with RTP, so tell the RTP source
    // to stop giving them to us:
    fSource->deregisterForMultiplexedRTCPPackets();
    fRTCPInterface.forgetOurGroupsock();
      // so that the "fRTCPInterface" destructor doesn't turn off background read handling
  }

  if (fSpecificRRHandlerTable != NULL) {
    AddressPortLookupTable::Iterator iter(*fSpecificRRHandlerTable);
    RRHandlerRecord* rrHandler;
    while ((rrHandler = (RRHandlerRecord*)iter.next()) != NULL) {
      delete rrHandler;
    }
    delete fSpecificRRHandlerTable;
  }

  delete fKnownMembers;
  delete fOutBuf;
  delete[] fInBuf;
}

void RTCPInstance::noteArrivingRR(struct sockaddr_in const& fromAddressAndPort,
				  int tcpSocketNum, unsigned char tcpStreamChannelId) {
  // If a 'RR handler' was set, call it now:

  // Specific RR handler:
  if (fSpecificRRHandlerTable != NULL) {
    netAddressBits fromAddr;
    portNumBits fromPortNum;
    if (tcpSocketNum < 0) {
      // Normal case: We read the RTCP packet over UDP
      fromAddr = fromAddressAndPort.sin_addr.s_addr;
      fromPortNum = ntohs(fromAddressAndPort.sin_port);
    } else {
      // Special case: We read the RTCP packet over TCP (interleaved)
      // Hack: Use the TCP socket and channel id to look up the handler
      fromAddr = tcpSocketNum;
      fromPortNum = tcpStreamChannelId;
    }
    Port fromPort(fromPortNum);
    RRHandlerRecord* rrHandler
      = (RRHandlerRecord*)(fSpecificRRHandlerTable->Lookup(fromAddr, (~0), fromPort));
    if (rrHandler != NULL) {
      if (rrHandler->rrHandlerTask != NULL) {
	(*(rrHandler->rrHandlerTask))(rrHandler->rrHandlerClientData);
      }
    }
  }
  
  // General RR handler:
  if (fRRHandlerTask != NULL) (*fRRHandlerTask)(fRRHandlerClientData);
}

RTCPInstance* RTCPInstance::createNew(UsageEnvironment& env, Groupsock* RTCPgs,
				      unsigned totSessionBW,
				      unsigned char const* cname,
				      RTPSink* sink, RTPSource* source,
				      Boolean isSSMTransmitter,
				      SRTPCryptographicContext* crypt) {
  return new RTCPInstance(env, RTCPgs, totSessionBW, cname, sink, source,
			  isSSMTransmitter, crypt);
}

Boolean RTCPInstance::lookupByName(UsageEnvironment& env,
				   char const* instanceName,
				   RTCPInstance*& resultInstance) {
  resultInstance = NULL; // unless we succeed

  Medium* medium;
  if (!Medium::lookupByName(env, instanceName, medium)) return False;

  if (!medium->isRTCPInstance()) {
    env.setResultMsg(instanceName, " is not a RTCP instance");
    return False;
  }

  resultInstance = (RTCPInstance*)medium;
  return True;
}

Boolean RTCPInstance::isRTCPInstance() const {
  return True;
}

unsigned RTCPInstance::numMembers() const {
  if (fKnownMembers == NULL) return 0;

  return fKnownMembers->numMembers();
}

void RTCPInstance::setByeHandler(TaskFunc* handlerTask, void* clientData,
				 Boolean handleActiveParticipantsOnly) {
  fByeHandlerTask = handlerTask;
  fByeWithReasonHandlerTask = NULL;
  fByeHandlerClientData = clientData;
  fByeHandleActiveParticipantsOnly = handleActiveParticipantsOnly;
}

void RTCPInstance::setByeWithReasonHandler(ByeWithReasonHandlerFunc* handlerTask, void* clientData,
					   Boolean handleActiveParticipantsOnly) {
  fByeHandlerTask = NULL;
  fByeWithReasonHandlerTask = handlerTask;
  fByeHandlerClientData = clientData;
  fByeHandleActiveParticipantsOnly = handleActiveParticipantsOnly;
}

void RTCPInstance::setSRHandler(TaskFunc* handlerTask, void* clientData) {
  fSRHandlerTask = handlerTask;
  fSRHandlerClientData = clientData;
}

void RTCPInstance::setRRHandler(TaskFunc* handlerTask, void* clientData) {
  fRRHandlerTask = handlerTask;
  fRRHandlerClientData = clientData;
}

void RTCPInstance
::setSpecificRRHandler(netAddressBits fromAddress, Port fromPort,
		       TaskFunc* handlerTask, void* clientData) {
  if (handlerTask == NULL && clientData == NULL) {
    unsetSpecificRRHandler(fromAddress, fromPort);
    return;
  }

  RRHandlerRecord* rrHandler = new RRHandlerRecord;
  rrHandler->rrHandlerTask = handlerTask;
  rrHandler->rrHandlerClientData = clientData;
  if (fSpecificRRHandlerTable == NULL) {
    fSpecificRRHandlerTable = new AddressPortLookupTable;
  }
  RRHandlerRecord* existingRecord = (RRHandlerRecord*)fSpecificRRHandlerTable->Add(fromAddress, (~0), fromPort, rrHandler);
  delete existingRecord; // if any

}

void RTCPInstance
::unsetSpecificRRHandler(netAddressBits fromAddress, Port fromPort) {
  if (fSpecificRRHandlerTable == NULL) return;

  RRHandlerRecord* rrHandler
    = (RRHandlerRecord*)(fSpecificRRHandlerTable->Lookup(fromAddress, (~0), fromPort));
  if (rrHandler != NULL) {
    fSpecificRRHandlerTable->Remove(fromAddress, (~0), fromPort);
    delete rrHandler;
  }
}

void RTCPInstance::setAppHandler(RTCPAppHandlerFunc* handlerTask, void* clientData) {
  fAppHandlerTask = handlerTask;
  fAppHandlerClientData = clientData;
}

void RTCPInstance::sendAppPacket(u_int8_t subtype, char const* name,
				 u_int8_t* appDependentData, unsigned appDependentDataSize) {
  // Set up the first 4 bytes: V,PT,subtype,PT,length:
  u_int32_t rtcpHdr = 0x80000000; // version 2, no padding
  rtcpHdr |= (subtype&0x1F)<<24;
  rtcpHdr |= (RTCP_PT_APP<<16);
  unsigned length = 2 + (appDependentDataSize+3)/4;
  rtcpHdr |= (length&0xFFFF);
  fOutBuf->enqueueWord(rtcpHdr);

  // Set up the next 4 bytes: SSRC:
  fOutBuf->enqueueWord(fSource != NULL ? fSource->SSRC() : fSink != NULL ? fSink->SSRC() : 0);

  // Set up the next 4 bytes: name:
  char nameBytes[4];
  nameBytes[0] = nameBytes[1] = nameBytes[2] = nameBytes[3] = '\0'; // by default
  if (name != NULL) {
    snprintf(nameBytes, 4, "%s", name);
  }
  fOutBuf->enqueue((u_int8_t*)nameBytes, 4);

  // Set up the remaining bytes (if any): application-dependent data (+ padding):
  if (appDependentData != NULL && appDependentDataSize > 0) {
    fOutBuf->enqueue(appDependentData, appDependentDataSize);

    unsigned modulo = appDependentDataSize%4;
    unsigned paddingSize = modulo == 0 ? 0 : 4-modulo;
    u_int8_t const paddingByte = 0x00;
    for (unsigned i = 0; i < paddingSize; ++i) fOutBuf->enqueue(&paddingByte, 1);
  }

  // Finally, send the packet:
  sendBuiltPacket();
}

void RTCPInstance::setStreamSocket(int sockNum,
				   unsigned char streamChannelId) {
  // Turn off background read handling:
  fRTCPInterface.stopNetworkReading();

  // Switch to RTCP-over-TCP:
  fRTCPInterface.setStreamSocket(sockNum, streamChannelId);

  // Turn background reading back on:
  TaskScheduler::BackgroundHandlerProc* handler
    = (TaskScheduler::BackgroundHandlerProc*)&incomingReportHandler;
  fRTCPInterface.startNetworkReading(handler);
}

void RTCPInstance::addStreamSocket(int sockNum,
				   unsigned char streamChannelId) {
  // First, turn off background read handling for the default (UDP) socket:
  envir().taskScheduler().turnOffBackgroundReadHandling(fRTCPInterface.gs()->socketNum());

  // Add the RTCP-over-TCP interface:
  fRTCPInterface.addStreamSocket(sockNum, streamChannelId);

  // Turn on background reading for this socket (in case it's not on already):
  TaskScheduler::BackgroundHandlerProc* handler
    = (TaskScheduler::BackgroundHandlerProc*)&incomingReportHandler;
  fRTCPInterface.startNetworkReading(handler);
}

void RTCPInstance
::injectReport(u_int8_t const* packet, unsigned packetSize, struct sockaddr_in const& fromAddress) {
  if (packetSize > maxRTCPPacketSize) packetSize = maxRTCPPacketSize;
  memmove(fInBuf, packet, packetSize);

  processIncomingReport(packetSize, fromAddress, -1, 0xFF); // assume report received over UDP
}

static unsigned const IP_UDP_HDR_SIZE = 28;
    // overhead (bytes) of IP and UDP hdrs

#define ADVANCE(n) pkt += (n); packetSize -= (n)

void RTCPInstance::incomingReportHandler(RTCPInstance* instance,
					 int /*mask*/) {
  instance->incomingReportHandler1();
}

void RTCPInstance::incomingReportHandler1() {
  do {
    if (fNumBytesAlreadyRead >= maxRTCPPacketSize) {
      envir() << "RTCPInstance error: Hit limit when reading incoming packet over TCP. (fNumBytesAlreadyRead ("
	      << fNumBytesAlreadyRead << ") >= maxRTCPPacketSize (" << maxRTCPPacketSize
	      << ")).  The remote endpoint is using a buggy implementation of RTP/RTCP-over-TCP.  Please upgrade it!\n";
      break;
    }

    unsigned numBytesRead;
    struct sockaddr_in fromAddress;
    int tcpSocketNum;
    unsigned char tcpStreamChannelId;
    Boolean packetReadWasIncomplete;
    Boolean readResult
      = fRTCPInterface.handleRead(&fInBuf[fNumBytesAlreadyRead], maxRTCPPacketSize - fNumBytesAlreadyRead,
				  numBytesRead, fromAddress,
				  tcpSocketNum, tcpStreamChannelId,
				  packetReadWasIncomplete);

    unsigned packetSize = 0;
    if (packetReadWasIncomplete) {
      fNumBytesAlreadyRead += numBytesRead;
      return; // more reads are needed to get the entire packet
    } else { // normal case: We've read the entire packet 
      packetSize = fNumBytesAlreadyRead + numBytesRead;
      fNumBytesAlreadyRead = 0; // for next time
    }
    if (!readResult) break;

    // Ignore the packet if it was looped-back from ourself:
    Boolean packetWasFromOurHost = False;
    if (RTCPgs()->wasLoopedBackFromUs(envir(), fromAddress)) {
      packetWasFromOurHost = True;
      // However, we still want to handle incoming RTCP packets from
      // *other processes* on the same machine.  To distinguish this
      // case from a true loop-back, check whether we've just sent a
      // packet of the same size.  (This check isn't perfect, but it seems
      // to be the best we can do.)
      if (fHaveJustSentPacket && fLastPacketSentSize == packetSize) {
	// This is a true loop-back:
	fHaveJustSentPacket = False;
	break; // ignore this packet
      }
    }

    if (fIsSSMTransmitter && !packetWasFromOurHost) {
      // This packet is assumed to have been received via unicast (because we're
      // a SSM transmitter, and SSM receivers send back RTCP "RR" packets via unicast).
      // 'Reflect' the packet by resending it to the multicast group, so that any other receivers
      // can also get to see it.

      // NOTE: Denial-of-service attacks are possible here.
      // Users of this software may wish to add their own,
      // application-specific mechanism for 'authenticating' the
      // validity of this packet before reflecting it.

      // NOTE: The test for "!packetWasFromOurHost" means that we won't reflect RTCP packets
      // that come from other processes on the same host as us.  The reason for this is that the
      // 'packet size' test above is not 100% reliable; some packets that were truly looped back
      // from us might not be detected as such, and this might lead to infinite
      // forwarding/receiving of some packets.  To avoid this possibility, we reflect only
      // RTCP packets that we know for sure originated elsewhere.
      // (Note, though, that if we ever re-enable the code in "Groupsock::multicastSendOnly()",
      // then we could remove the test for "!packetWasFromOurHost".)
      fRTCPInterface.sendPacket(fInBuf, packetSize);
      fHaveJustSentPacket = True;
      fLastPacketSentSize = packetSize;
    }

    processIncomingReport(packetSize, fromAddress, tcpSocketNum, tcpStreamChannelId);
  } while (0);
}

void RTCPInstance
::processIncomingReport(unsigned packetSize, struct sockaddr_in const& fromAddressAndPort,
			int tcpSocketNum, unsigned char tcpStreamChannelId) {
  do {
    if (fCrypto != NULL) { // The packet is assumed to be SRTCP.  Verify/decrypt it first:
      unsigned newPacketSize;
      if (!fCrypto->processIncomingSRTCPPacket(fInBuf, packetSize, newPacketSize)) break;
      packetSize = newPacketSize;
    }

    Boolean callByeHandler = False;
    char* reason = NULL; // by default, unless/until a BYE packet with a 'reason' arrives
    unsigned char* pkt = fInBuf;

#ifdef DEBUG
    fprintf(stderr, "[%p]saw incoming RTCP packet (from ", this);
    if (tcpSocketNum < 0) {
      // Note that "fromAddressAndPort" is valid only if we're receiving over UDP (not over TCP):
      fprintf(stderr, "address %s, port %d", AddressString(fromAddressAndPort).val(), ntohs(fromAddressAndPort.sin_port));
    } else {
      fprintf(stderr, "TCP socket #%d, stream channel id %d", tcpSocketNum, tcpStreamChannelId);
    }
    fprintf(stderr, ")\n");
    for (unsigned i = 0; i < packetSize; ++i) {
      if (i%4 == 0) fprintf(stderr, " ");
      fprintf(stderr, "%02x", pkt[i]);
    }
    fprintf(stderr, "\n");
#endif
    int totPacketSize = IP_UDP_HDR_SIZE + packetSize;

    // Check the RTCP packet for validity:
    // It must at least contain a header (4 bytes), and this header
    // must be version=2, with no padding bit, and a payload type of
    // SR (200), RR (201), or APP (204):
    if (packetSize < 4) break;
    unsigned rtcpHdr = ntohl(*(u_int32_t*)pkt);
    if ((rtcpHdr & 0xE0FE0000) != (0x80000000 | (RTCP_PT_SR<<16)) &&
	(rtcpHdr & 0xE0FF0000) != (0x80000000 | (RTCP_PT_APP<<16))) {
#ifdef DEBUG
      fprintf(stderr, "rejected bad RTCP packet: header 0x%08x\n", rtcpHdr);
#endif
      break;
    }

    // Process each of the individual RTCP 'subpackets' in (what may be)
    // a compound RTCP packet.
    int typeOfPacket = PACKET_UNKNOWN_TYPE;
    unsigned reportSenderSSRC = 0;
    Boolean packetOK = False;
    while (1) {
      u_int8_t rc = (rtcpHdr>>24)&0x1F;
      u_int8_t pt = (rtcpHdr>>16)&0xFF;
      unsigned length = 4*(rtcpHdr&0xFFFF); // doesn't count hdr
      ADVANCE(4); // skip over the header
      if (length > packetSize) break;

      // Assume that each RTCP subpacket begins with a 4-byte SSRC:
      if (length < 4) break; length -= 4;
      reportSenderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
#ifdef HACK_FOR_CHROME_WEBRTC_BUG
      if (reportSenderSSRC == 0x00000001 && pt == RTCP_PT_RR) {
	// Chrome (and Opera) WebRTC receivers have a bug that causes them to always send
	// SSRC 1 in their "RR"s.  To work around this (to help us distinguish between different
	// receivers), we use a fake SSRC in this case consisting of the IP address, XORed with
	// the port number:
	reportSenderSSRC = fromAddressAndPort.sin_addr.s_addr^fromAddressAndPort.sin_port;
      }
#endif

      Boolean subPacketOK = False;
      switch (pt) {
        case RTCP_PT_SR: {
#ifdef DEBUG
	  fprintf(stderr, "SR\n");
#endif
	  if (length < 20) break; length -= 20;

	  // Extract the NTP timestamp, and note this:
	  unsigned NTPmsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
	  unsigned NTPlsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
	  unsigned rtpTimestamp = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
	  if (fSource != NULL) {
	    RTPReceptionStatsDB& receptionStats
	      = fSource->receptionStatsDB();
	    receptionStats.noteIncomingSR(reportSenderSSRC,
					  NTPmsw, NTPlsw, rtpTimestamp);
	  }
	  ADVANCE(8); // skip over packet count, octet count

	  // If a 'SR handler' was set, call it now:
	  if (fSRHandlerTask != NULL) (*fSRHandlerTask)(fSRHandlerClientData);

	  // The rest of the SR is handled like a RR (so, no "break;" here)
	}
        case RTCP_PT_RR: {
#ifdef DEBUG
	  fprintf(stderr, "RR\n");
#endif
	  unsigned reportBlocksSize = rc*(6*4);
	  if (length < reportBlocksSize) break;
	  length -= reportBlocksSize;

          if (fSink != NULL) {
	    // Use this information to update stats about our transmissions:
            RTPTransmissionStatsDB& transmissionStats = fSink->transmissionStatsDB();
            for (unsigned i = 0; i < rc; ++i) {
              unsigned senderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
              // We care only about reports about our own transmission, not others'
              if (senderSSRC == fSink->SSRC()) {
                unsigned lossStats = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                unsigned highestReceived = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                unsigned jitter = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                unsigned timeLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                unsigned timeSinceLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                transmissionStats.noteIncomingRR(reportSenderSSRC, fromAddressAndPort,
						 lossStats,
						 highestReceived, jitter,
						 timeLastSR, timeSinceLastSR);
              } else {
                ADVANCE(4*5);
              }
            }
          } else {
            ADVANCE(reportBlocksSize);
          }

	  if (pt == RTCP_PT_RR) { // i.e., we didn't fall through from 'SR'
	    noteArrivingRR(fromAddressAndPort, tcpSocketNum, tcpStreamChannelId);
	  }

	  subPacketOK = True;
	  typeOfPacket = PACKET_RTCP_REPORT;
	  break;
	}
        case RTCP_PT_BYE: {
#ifdef DEBUG
	  fprintf(stderr, "BYE");
#endif
	  // Check whether there was a 'reason for leaving':
	  if (length > 0) {
	    u_int8_t reasonLength = *pkt;
	    if (reasonLength > length-1) {
	      // The 'reason' length field is too large!
#ifdef DEBUG
	      fprintf(stderr, "\nError: The 'reason' length %d is too large (it should be <= %d)\n",
		      reasonLength, length-1);
#endif
	      reasonLength = length-1;
	    }
	    reason = new char[reasonLength + 1];
	    for (unsigned i = 0; i < reasonLength; ++i) {
	      reason[i] = pkt[1+i];
	    }
	    reason[reasonLength] = '\0';
#ifdef DEBUG
	    fprintf(stderr, " (reason:%s)", reason);
#endif
	  }
#ifdef DEBUG
	  fprintf(stderr, "\n");
#endif
	  // If a 'BYE handler' was set, arrange for it to be called at the end of this routine.
	  // (Note: We don't call it immediately, in case it happens to cause "this" to be deleted.)
	  if ((fByeHandlerTask != NULL || fByeWithReasonHandlerTask != NULL)
	      && (!fByeHandleActiveParticipantsOnly
		  || (fSource != NULL
		      && fSource->receptionStatsDB().lookup(reportSenderSSRC) != NULL)
		  || (fSink != NULL
		      && fSink->transmissionStatsDB().lookup(reportSenderSSRC) != NULL))) {
	    callByeHandler = True;
	  }

	  // We should really check for & handle >1 SSRCs being present #####

	  subPacketOK = True;
	  typeOfPacket = PACKET_BYE;
	  break;
	}
        case RTCP_PT_APP: {
	  u_int8_t& subtype = rc; // In "APP" packets, the "rc" field gets used as "subtype"
#ifdef DEBUG
	  fprintf(stderr, "APP (subtype 0x%02x)\n", subtype);
#endif
	  if (length < 4) {
#ifdef DEBUG
	    fprintf(stderr, "\tError: No \"name\" field!\n");
#endif
	    break;
	  }
	  length -= 4;
#ifdef DEBUG
	  fprintf(stderr, "\tname:%c%c%c%c\n", pkt[0], pkt[1], pkt[2], pkt[3]);
#endif
	  u_int32_t nameBytes = (pkt[0]<<24)|(pkt[1]<<16)|(pkt[2]<<8)|(pkt[3]);
	  ADVANCE(4); // skip over "name", to the 'application-dependent data'
#ifdef DEBUG
	  fprintf(stderr, "\tapplication-dependent data size: %d bytes\n", length);
#endif

	  // If an 'APP' packet handler was set, call it now:
	  if (fAppHandlerTask != NULL) {
	    (*fAppHandlerTask)(fAppHandlerClientData, subtype, nameBytes, pkt, length);
	  }
	  subPacketOK = True;
	  typeOfPacket = PACKET_RTCP_APP;
	  break;
	}
	// Other RTCP packet types that we don't yet handle:
        case RTCP_PT_SDES: {
#ifdef DEBUG
	  // 'Handle' SDES packets only in debugging code, by printing out the 'SDES items':
	  fprintf(stderr, "SDES\n");

	  // Process each 'chunk':
	  Boolean chunkOK = False;
	  ADVANCE(-4); length += 4; // hack so that we see the first SSRC/CSRC again
	  while (length >= 8) { // A valid chunk must be at least 8 bytes long
	    chunkOK = False; // until we learn otherwise

	    u_int32_t SSRC_CSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4); length -= 4;
	    fprintf(stderr, "\tSSRC/CSRC: 0x%08x\n", SSRC_CSRC);

	    // Process each 'SDES item' in the chunk:
	    u_int8_t itemType = *pkt; ADVANCE(1); --length;
	    while (itemType != 0) {
	      unsigned itemLen = *pkt; ADVANCE(1); --length;
	      // Make sure "itemLen" allows for at least 1 zero byte at the end of the chunk:
	      if (itemLen + 1 > length || pkt[itemLen] != 0) break;

	      fprintf(stderr, "\t\t%s:%s\n",
		      itemType == 1 ? "CNAME" :
		      itemType == 2 ? "NAME" :
		      itemType == 3 ? "EMAIL" :
		      itemType == 4 ? "PHONE" :
		      itemType == 5 ? "LOC" :
		      itemType == 6 ? "TOOL" :
		      itemType == 7 ? "NOTE" :
		      itemType == 8 ? "PRIV" :
		      "(unknown)",
		      itemType < 8 ? (char*)pkt // hack, because we know it's '\0'-terminated
		      : "???"/* don't try to print out PRIV or unknown items */);
	      ADVANCE(itemLen); length -= itemLen;

	      itemType = *pkt; ADVANCE(1); --length;
	    }
	    if (itemType != 0) break; // bad 'SDES item'

	    // Thus, itemType == 0.  This zero 'type' marks the end of the list of SDES items.
	    // Skip over remaining zero padding bytes, so that this chunk ends on a 4-byte boundary:
	    while (length%4 > 0 && *pkt == 0) { ADVANCE(1); --length; }
	    if (length%4 > 0) break; // Bad (non-zero) padding byte

	    chunkOK = True;
	  }
	  if (!chunkOK || length > 0) break; // bad chunk, or not enough bytes for the last chunk
#endif
	  subPacketOK = True;
	  break;
	}
        case RTCP_PT_RTPFB: {
#ifdef DEBUG
	  fprintf(stderr, "RTPFB(unhandled)\n");
#endif
	  subPacketOK = True;
	  break;
	}
        case RTCP_PT_PSFB: {
#ifdef DEBUG
	  fprintf(stderr, "PSFB(unhandled)\n");
	  // Temporary code to show "Receiver Estimated Maximum Bitrate" (REMB) feedback reports:
	  //#####
	  if (length >= 12 && pkt[4] == 'R' && pkt[5] == 'E' && pkt[6] == 'M' && pkt[7] == 'B') {
	    u_int8_t exp = pkt[9]>>2;
	    u_int32_t mantissa = ((pkt[9]&0x03)<<16)|(pkt[10]<<8)|pkt[11];
	    double remb = (double)mantissa;
	    while (exp > 0) {
	      remb *= 2.0;
	      exp /= 2;
	    }
	    fprintf(stderr, "\tReceiver Estimated Max Bitrate (REMB): %g bps\n", remb);
	  }
#endif
	  subPacketOK = True;
	  break;
	}
        case RTCP_PT_XR: {
#ifdef DEBUG
	  fprintf(stderr, "XR(unhandled)\n");
#endif
	  subPacketOK = True;
	  break;
	}
        case RTCP_PT_AVB: {
#ifdef DEBUG
	  fprintf(stderr, "AVB(unhandled)\n");
#endif
	  subPacketOK = True;
	  break;
	}
        case RTCP_PT_RSI: {
#ifdef DEBUG
	  fprintf(stderr, "RSI(unhandled)\n");
#endif
	  subPacketOK = True;
	  break;
	}
        case RTCP_PT_TOKEN: {
#ifdef DEBUG
	  fprintf(stderr, "TOKEN(unhandled)\n");
#endif
	  subPacketOK = True;
	  break;
	}
        case RTCP_PT_IDMS: {
#ifdef DEBUG
	  fprintf(stderr, "IDMS(unhandled)\n");
#endif
	  subPacketOK = True;
	  break;
	}
        default: {
#ifdef DEBUG
	  fprintf(stderr, "UNKNOWN TYPE(0x%x)\n", pt);
#endif
	  subPacketOK = True;
	  break;
	}
      }
      if (!subPacketOK) break;

      // need to check for (& handle) SSRC collision! #####

#ifdef DEBUG
      fprintf(stderr, "validated RTCP subpacket: rc:%d, pt:%d, bytes remaining:%d, report sender SSRC:0x%08x\n", rc, pt, length, reportSenderSSRC);
#endif

      // Skip over any remaining bytes in this subpacket:
      ADVANCE(length);

      // Check whether another RTCP 'subpacket' follows:
      if (packetSize == 0) {
	packetOK = True;
	break;
      } else if (packetSize < 4) {
#ifdef DEBUG
	fprintf(stderr, "extraneous %d bytes at end of RTCP packet!\n", packetSize);
#endif
	break;
      }
      rtcpHdr = ntohl(*(u_int32_t*)pkt);
      if ((rtcpHdr & 0xC0000000) != 0x80000000) {
#ifdef DEBUG
	fprintf(stderr, "bad RTCP subpacket: header 0x%08x\n", rtcpHdr);
#endif
	break;
      }
    }

    if (!packetOK) {
#ifdef DEBUG
      fprintf(stderr, "rejected bad RTCP subpacket: header 0x%08x\n", rtcpHdr);
#endif
      break;
    } else {
#ifdef DEBUG
      fprintf(stderr, "validated entire RTCP packet\n");
#endif
    }

    onReceive(typeOfPacket, totPacketSize, reportSenderSSRC);

    // Finally, if we need to call a "BYE" handler, do so now (in case it causes "this" to get deleted):
    if (callByeHandler) {
      if (fByeHandlerTask != NULL) { // call a BYE handler without including a 'reason'
	TaskFunc* byeHandler = fByeHandlerTask;
	fByeHandlerTask = NULL; // because we call the handler only once, by default
	(*byeHandler)(fByeHandlerClientData);
      } else if (fByeWithReasonHandlerTask != NULL) { // call a BYE handler that includes a 'reason'
	ByeWithReasonHandlerFunc* byeHandler = fByeWithReasonHandlerTask;
	fByeWithReasonHandlerTask = NULL; // because we call the handler only once, by default
	(*byeHandler)(fByeHandlerClientData, reason);
	    // Note that the handler function is responsible for delete[]ing "reason"
      }
    }
  } while (0);
}

void RTCPInstance::onReceive(int typeOfPacket, int totPacketSize, u_int32_t ssrc) {
  fTypeOfPacket = typeOfPacket;
  fLastReceivedSize = totPacketSize;
  fLastReceivedSSRC = ssrc;

  int members = (int)numMembers();
  int senders = (fSink != NULL) ? 1 : 0;

  OnReceive(this, // p
	    this, // e
	    &members, // members
	    &fPrevNumMembers, // pmembers
	    &senders, // senders
	    &fAveRTCPSize, // avg_rtcp_size
	    &fPrevReportTime, // tp
	    dTimeNow(), // tc
	    fNextReportTime);
}

void RTCPInstance::sendReport() {
#ifdef DEBUG
  fprintf(stderr, "sending REPORT\n");
#endif
  // Begin by including a SR and/or RR report:
  if (!addReport()) return;

  // Then, include a SDES:
  addSDES();

  // Send the report:
  sendBuiltPacket();

  // Periodically clean out old members from our SSRC membership database:
  const unsigned membershipReapPeriod = 5;
  if ((++fOutgoingReportCount) % membershipReapPeriod == 0) {
    unsigned threshold = fOutgoingReportCount - membershipReapPeriod;
    fKnownMembers->reapOldMembers(threshold);
  }
}

void RTCPInstance::sendBYE(char const* reason) {
#ifdef DEBUG
  if (reason != NULL) {
    fprintf(stderr, "sending BYE (reason:%s)\n", reason);
  } else {
    fprintf(stderr, "sending BYE\n");
  }
#endif
  // The packet must begin with a SR and/or RR report:
  (void)addReport(True);

  addBYE(reason);
  sendBuiltPacket();
}

void RTCPInstance::sendBuiltPacket() {
#ifdef DEBUG
  fprintf(stderr, "sending RTCP packet\n");
  unsigned char* p = fOutBuf->packet();
  for (unsigned i = 0; i < fOutBuf->curPacketSize(); ++i) {
    if (i%4 == 0) fprintf(stderr," ");
    fprintf(stderr, "%02x", p[i]);
  }
  fprintf(stderr, "\n");
#endif
  unsigned reportSize = fOutBuf->curPacketSize();
  if (fCrypto != NULL) { // Encrypt/tag the data before sending it:
    unsigned newReportSize;
    if (!fCrypto->processOutgoingSRTCPPacket(fOutBuf->packet(), reportSize, newReportSize)) return;
    reportSize = newReportSize;
  }
  fRTCPInterface.sendPacket(fOutBuf->packet(), reportSize);
  fOutBuf->resetOffset();

  fLastSentSize = IP_UDP_HDR_SIZE + reportSize;
  fHaveJustSentPacket = True;
  fLastPacketSentSize = reportSize;
}

int RTCPInstance::checkNewSSRC() {
  return fKnownMembers->noteMembership(fLastReceivedSSRC,
				       fOutgoingReportCount);
}

void RTCPInstance::removeLastReceivedSSRC() {
  removeSSRC(fLastReceivedSSRC, False/*keep stats around*/);
}

void RTCPInstance::removeSSRC(u_int32_t ssrc, Boolean alsoRemoveStats) {
  fKnownMembers->remove(ssrc);

  if (alsoRemoveStats) {
    // Also, remove records of this SSRC from any reception or transmission stats
    if (fSource != NULL) fSource->receptionStatsDB().removeRecord(ssrc);
    if (fSink != NULL) fSink->transmissionStatsDB().removeRecord(ssrc);
  }
}

void RTCPInstance::onExpire(RTCPInstance* instance) {
  instance->onExpire1();
}

// Member functions to build specific kinds of report:

Boolean RTCPInstance::addReport(Boolean alwaysAdd) {
  // Include a SR or a RR, depending on whether we have an associated sink or source:
  if (fSink != NULL) {
    if (!alwaysAdd) {
      if (!fSink->enableRTCPReports()) return False;

      // Hack: Don't send a SR during those (brief) times when the timestamp of the
      // next outgoing RTP packet has been preset, to ensure that that timestamp gets
      // used for that outgoing packet. (David Bertrand, 2006.07.18)
      if (fSink->nextTimestampHasBeenPreset()) return False;
    }

    addSR();
  }
  if (fSource != NULL) {
    if (!alwaysAdd) {
      if (!fSource->enableRTCPReports()) return False;
    }

    addRR();
  }

  return True;
}

void RTCPInstance::addSR() {
  // ASSERT: fSink != NULL

  enqueueCommonReportPrefix(RTCP_PT_SR, fSink->SSRC(),
			    5 /* extra words in a SR */);

  // Now, add the 'sender info' for our sink

  // Insert the NTP and RTP timestamps for the 'wallclock time':
  struct timeval timeNow;
  gettimeofday(&timeNow, NULL);
  fOutBuf->enqueueWord(timeNow.tv_sec + 0x83AA7E80);
      // NTP timestamp most-significant word (1970 epoch -> 1900 epoch)
  double fractionalPart = (timeNow.tv_usec/15625.0)*0x04000000; // 2^32/10^6
  fOutBuf->enqueueWord((unsigned)(fractionalPart+0.5));
      // NTP timestamp least-significant word
  unsigned rtpTimestamp = fSink->convertToRTPTimestamp(timeNow);
  fOutBuf->enqueueWord(rtpTimestamp); // RTP ts

  // Insert the packet and byte counts:
  fOutBuf->enqueueWord(fSink->packetCount());
  fOutBuf->enqueueWord(fSink->octetCount());

  enqueueCommonReportSuffix();
}

void RTCPInstance::addRR() {
  // ASSERT: fSource != NULL

  enqueueCommonReportPrefix(RTCP_PT_RR, fSource->SSRC());
  enqueueCommonReportSuffix();
}

void RTCPInstance::enqueueCommonReportPrefix(unsigned char packetType,
					     u_int32_t SSRC,
					     unsigned numExtraWords) {
  unsigned numReportingSources;
  if (fSource == NULL) {
    numReportingSources = 0; // we don't receive anything
  } else {
    RTPReceptionStatsDB& allReceptionStats
      = fSource->receptionStatsDB();
    numReportingSources = allReceptionStats.numActiveSourcesSinceLastReset();
    // This must be <32, to fit in 5 bits:
    if (numReportingSources >= 32) { numReportingSources = 32; }
    // Later: support adding more reports to handle >32 sources (unlikely)#####
  }

  unsigned rtcpHdr = 0x80000000; // version 2, no padding
  rtcpHdr |= (numReportingSources<<24);
  rtcpHdr |= (packetType<<16);
  rtcpHdr |= (1 + numExtraWords + 6*numReportingSources);
      // each report block is 6 32-bit words long
  fOutBuf->enqueueWord(rtcpHdr);

  fOutBuf->enqueueWord(SSRC);
}

void RTCPInstance::enqueueCommonReportSuffix() {
  // Output the report blocks for each source:
  if (fSource != NULL) {
    RTPReceptionStatsDB& allReceptionStats
      = fSource->receptionStatsDB();

    RTPReceptionStatsDB::Iterator iterator(allReceptionStats);
    while (1) {
      RTPReceptionStats* receptionStats = iterator.next();
      if (receptionStats == NULL) break;
      enqueueReportBlock(receptionStats);
    }

    allReceptionStats.reset(); // because we have just generated a report
  }
}

void
RTCPInstance::enqueueReportBlock(RTPReceptionStats* stats) {
  fOutBuf->enqueueWord(stats->SSRC());

  unsigned highestExtSeqNumReceived = stats->highestExtSeqNumReceived();

  unsigned totNumExpected
    = highestExtSeqNumReceived - stats->baseExtSeqNumReceived();
  int totNumLost = totNumExpected - stats->totNumPacketsReceived();
  // 'Clamp' this loss number to a 24-bit signed value:
  if (totNumLost > 0x007FFFFF) {
    totNumLost = 0x007FFFFF;
  } else if (totNumLost < 0) {
    if (totNumLost < -0x00800000) totNumLost = 0x00800000; // unlikely, but...
    totNumLost &= 0x00FFFFFF;
  }

  unsigned numExpectedSinceLastReset
    = highestExtSeqNumReceived - stats->lastResetExtSeqNumReceived();
  int numLostSinceLastReset
    = numExpectedSinceLastReset - stats->numPacketsReceivedSinceLastReset();
  unsigned char lossFraction;
  if (numExpectedSinceLastReset == 0 || numLostSinceLastReset < 0) {
    lossFraction = 0;
  } else {
    lossFraction = (unsigned char)
      ((numLostSinceLastReset << 8) / numExpectedSinceLastReset);
  }

  fOutBuf->enqueueWord((lossFraction<<24) | totNumLost);
  fOutBuf->enqueueWord(highestExtSeqNumReceived);

  fOutBuf->enqueueWord(stats->jitter());

  unsigned NTPmsw = stats->lastReceivedSR_NTPmsw();
  unsigned NTPlsw = stats->lastReceivedSR_NTPlsw();
  unsigned LSR = ((NTPmsw&0xFFFF)<<16)|(NTPlsw>>16); // middle 32 bits
  fOutBuf->enqueueWord(LSR);

  // Figure out how long has elapsed since the last SR rcvd from this src:
  struct timeval const& LSRtime = stats->lastReceivedSR_time(); // "last SR"
  struct timeval timeNow, timeSinceLSR;
  gettimeofday(&timeNow, NULL);
  if (timeNow.tv_usec < LSRtime.tv_usec) {
    timeNow.tv_usec += 1000000;
    timeNow.tv_sec -= 1;
  }
  timeSinceLSR.tv_sec = timeNow.tv_sec - LSRtime.tv_sec;
  timeSinceLSR.tv_usec = timeNow.tv_usec - LSRtime.tv_usec;
  // The enqueued time is in units of 1/65536 seconds.
  // (Note that 65536/1000000 == 1024/15625)
  unsigned DLSR;
  if (LSR == 0) {
    DLSR = 0;
  } else {
    DLSR = (timeSinceLSR.tv_sec<<16)
         | ( (((timeSinceLSR.tv_usec<<11)+15625)/31250) & 0xFFFF);
  }
  fOutBuf->enqueueWord(DLSR);
}

void RTCPInstance::addSDES() {
  // For now we support only the CNAME item; later support more #####

  // Begin by figuring out the size of the entire SDES report:
  unsigned numBytes = 4;
      // counts the SSRC, but not the header; it'll get subtracted out
  numBytes += fCNAME.totalSize(); // includes id and length
  numBytes += 1; // the special END item

  unsigned num4ByteWords = (numBytes + 3)/4;

  unsigned rtcpHdr = 0x81000000; // version 2, no padding, 1 SSRC chunk
  rtcpHdr |= (RTCP_PT_SDES<<16);
  rtcpHdr |= num4ByteWords;
  fOutBuf->enqueueWord(rtcpHdr);

  if (fSource != NULL) {
    fOutBuf->enqueueWord(fSource->SSRC());
  } else if (fSink != NULL) {
    fOutBuf->enqueueWord(fSink->SSRC());
  }

  // Add the CNAME:
  fOutBuf->enqueue(fCNAME.data(), fCNAME.totalSize());

  // Add the 'END' item (i.e., a zero byte), plus any more needed to pad:
  unsigned numPaddingBytesNeeded = 4 - (fOutBuf->curPacketSize() % 4);
  unsigned char const zero = '\0';
  while (numPaddingBytesNeeded-- > 0) fOutBuf->enqueue(&zero, 1);
}

void RTCPInstance::addBYE(char const* reason) {
  u_int32_t rtcpHdr = 0x81000000; // version 2, no padding, 1 SSRC
  rtcpHdr |= (RTCP_PT_BYE<<16);
  u_int16_t num32BitWords = 2; // by default, two 32-bit words total (i.e., with 1 SSRC)
  u_int8_t reasonLength8Bits = 0; // by default
  if (reason != NULL) {
    // We need to add more 32-bit words for the 'length+reason':
    unsigned const reasonLength = strlen(reason);
    reasonLength8Bits = reasonLength < 0xFF ? (u_int8_t)reasonLength : 0xFF;
    unsigned numExtraWords = ((1/*reason length field*/+reasonLength8Bits)+3)/4;
    
    num32BitWords += numExtraWords;
  }
  rtcpHdr |= (num32BitWords-1); // length field
  fOutBuf->enqueueWord(rtcpHdr);

  if (fSource != NULL) {
    fOutBuf->enqueueWord(fSource->SSRC());
  } else if (fSink != NULL) {
    fOutBuf->enqueueWord(fSink->SSRC());
  }

  num32BitWords -= 2; // ASSERT: num32BitWords >= 0
  if (num32BitWords > 0) {
    // Add a length+'reason for leaving':
    // First word:
    u_int32_t lengthPlusFirst3ReasonBytes = reasonLength8Bits<<24;
    unsigned index = 0;
    if (reasonLength8Bits > index) lengthPlusFirst3ReasonBytes |= ((u_int8_t)reason[index++])<<16;
    if (reasonLength8Bits > index) lengthPlusFirst3ReasonBytes |= ((u_int8_t)reason[index++])<<8;
    if (reasonLength8Bits > index) lengthPlusFirst3ReasonBytes |= (u_int8_t)reason[index++];
    fOutBuf->enqueueWord(lengthPlusFirst3ReasonBytes);

    // Any subsequent words:
    if (reasonLength8Bits > 3) {
      // ASSERT: num32BitWords > 1
      while (--num32BitWords > 0) {
	u_int32_t fourMoreReasonBytes = 0;
	if (reasonLength8Bits > index) fourMoreReasonBytes |= ((u_int8_t)reason[index++])<<24;
	if (reasonLength8Bits > index) fourMoreReasonBytes |= ((u_int8_t)reason[index++])<<16;
	if (reasonLength8Bits > index) fourMoreReasonBytes |= ((u_int8_t)reason[index++])<<8;
	if (reasonLength8Bits > index) fourMoreReasonBytes |= (u_int8_t)reason[index++];
	fOutBuf->enqueueWord(fourMoreReasonBytes);
      }
    }
  }
}

void RTCPInstance::schedule(double nextTime) {
  fNextReportTime = nextTime;

  double secondsToDelay = nextTime - dTimeNow();
  if (secondsToDelay < 0) secondsToDelay = 0;
#ifdef DEBUG
  fprintf(stderr, "schedule(%f->%f)\n", secondsToDelay, nextTime);
#endif
  int64_t usToGo = (int64_t)(secondsToDelay * 1000000);
  nextTask() = envir().taskScheduler().scheduleDelayedTask(usToGo,
				(TaskFunc*)RTCPInstance::onExpire, this);
}

void RTCPInstance::reschedule(double nextTime) {
  envir().taskScheduler().unscheduleDelayedTask(nextTask());
  schedule(nextTime);
}

void RTCPInstance::onExpire1() {
  nextTask() = NULL;

  // Note: fTotSessionBW is kbits per second
  double rtcpBW = 0.05*fTotSessionBW*1024/8; // -> bytes per second

  OnExpire(this, // event
	   numMembers(), // members
	   (fSink != NULL) ? 1 : 0, // senders
	   rtcpBW, // rtcp_bw
	   (fSink != NULL) ? 1 : 0, // we_sent
	   &fAveRTCPSize, // ave_rtcp_size
	   &fIsInitial, // initial
	   dTimeNow(), // tc
	   &fPrevReportTime, // tp
	   &fPrevNumMembers // pmembers
	   );
}

////////// SDESItem //////////

SDESItem::SDESItem(unsigned char tag, unsigned char const* value) {
  unsigned length = strlen((char const*)value);
  if (length > 0xFF) length = 0xFF; // maximum data length for a SDES item

  fData[0] = tag;
  fData[1] = (unsigned char)length;
  memmove(&fData[2], value, length);
}

unsigned SDESItem::totalSize() const {
  return 2 + (unsigned)fData[1];
}


////////// Implementation of routines imported by the "rtcp_from_spec" C code

extern "C" void Schedule(double nextTime, event e) {
  RTCPInstance* instance = (RTCPInstance*)e;
  if (instance == NULL) return;

  instance->schedule(nextTime);
}

extern "C" void Reschedule(double nextTime, event e) {
  RTCPInstance* instance = (RTCPInstance*)e;
  if (instance == NULL) return;

  instance->reschedule(nextTime);
}

extern "C" void SendRTCPReport(event e) {
  RTCPInstance* instance = (RTCPInstance*)e;
  if (instance == NULL) return;

  instance->sendReport();
}

extern "C" void SendBYEPacket(event e) {
  RTCPInstance* instance = (RTCPInstance*)e;
  if (instance == NULL) return;

  instance->sendBYE();
}

extern "C" int TypeOfEvent(event e) {
  RTCPInstance* instance = (RTCPInstance*)e;
  if (instance == NULL) return EVENT_UNKNOWN;

  return instance->typeOfEvent();
}

extern "C" int SentPacketSize(event e) {
  RTCPInstance* instance = (RTCPInstance*)e;
  if (instance == NULL) return 0;

  return instance->sentPacketSize();
}

extern "C" int PacketType(packet p) {
  RTCPInstance* instance = (RTCPInstance*)p;
  if (instance == NULL) return PACKET_UNKNOWN_TYPE;

  return instance->packetType();
}

extern "C" int ReceivedPacketSize(packet p) {
  RTCPInstance* instance = (RTCPInstance*)p;
  if (instance == NULL) return 0;

  return instance->receivedPacketSize();
}

extern "C" int NewMember(packet p) {
  RTCPInstance* instance = (RTCPInstance*)p;
  if (instance == NULL) return 0;

  return instance->checkNewSSRC();
}

extern "C" int NewSender(packet /*p*/) {
  return 0; // we don't yet recognize senders other than ourselves #####
}

extern "C" void AddMember(packet /*p*/) {
  // Do nothing; all of the real work was done when NewMember() was called
}

extern "C" void AddSender(packet /*p*/) {
  // we don't yet recognize senders other than ourselves #####
}

extern "C" void RemoveMember(packet p) {
  RTCPInstance* instance = (RTCPInstance*)p;
  if (instance == NULL) return;

  instance->removeLastReceivedSSRC();
}

extern "C" void RemoveSender(packet /*p*/) {
  // we don't yet recognize senders other than ourselves #####
}

extern "C" double drand30() {
  unsigned tmp = our_random()&0x3FFFFFFF; // a random 30-bit integer
  return tmp/(double)(1024*1024*1024);
}
