windows-nt/Source/XPSP1/NT/enduser/netmeeting/av/rrcm/rtcp/rtcprept.cpp
2020-09-26 16:20:57 +08:00

457 lines
12 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*----------------------------------------------------------------------------
* File: RTCPREPT.C
* Product: RTP/RTCP implementation
* Description: Provides report functions for the RRCM implementation.
*
* INTEL Corporation Proprietary Information
* This listing is supplied under the terms of a license agreement with
* Intel Corporation and may not be copied nor disclosed except in
* accordance with the terms of that agreement.
* Copyright (c) 1995 Intel Corporation.
*--------------------------------------------------------------------------*/
#include "rrcm.h"
/*---------------------------------------------------------------------------
/ Global Variables
/--------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
/ External Variables
/--------------------------------------------------------------------------*/
extern PRTCP_CONTEXT pRTCPContext;
extern RRCM_WS RRCMws;
/*----------------------------------------------------------------------------
* Function : RTCPReportRequest
* Description: The application request a report for a particular RTCP
* session, identified by the socket descriptor.
*
* Input : RTCPsd: RTCP socket descriptor
* offset: Offset to start from in the list
* *status: -> to the report status information
* *moreEntries: -> to a flag
* numEntriesInBfr: Number of entries in buffer
* pReportBfr: -> to report buffer
* iFilterFlags Bit flags specifying filter to apply
* pFilterPattern -> to value of filter pattern to use
* dwFltrPtrnLen Filter pattern length
*
* Return: OK: RRCM_NoError
* !0: Error code (see RRCM.H)
---------------------------------------------------------------------------*/
HRESULT WINAPI RTCPReportRequest (SOCKET RTCPsd,
DWORD offset,
DWORD *status,
DWORD *moreEntries,
DWORD numEntriesInBfr,
PRTCP_REPORT pReportBfr,
DWORD dwFilterFlags,
LPVOID pFilterPattern,
DWORD dwFltrPtrnLen)
{
PLINK_LIST pTmp;
PSSRC_ENTRY pRRCM;
DWORD dwStatus = RRCM_NoError;
DWORD numEntryWritten = 0;
DWORD index;
DWORD dwLost;
DWORD dwTmp;
BOOL matched;
IN_OUT_STR ("RTCP: Enter RTCPReportRequest()\n");
ASSERT (pReportBfr);
ASSERT (numEntriesInBfr);
// look for the RTCP session
pTmp = pRTCPContext->RTCPSession.prev;
if (pTmp == NULL)
{
RRCM_DBG_MSG ("RTCP: ERROR - Invalid RTCP session", 0,
__FILE__, __LINE__, DBG_ERROR);
IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTCPInvalidSession));
}
pRRCM = (PSSRC_ENTRY)((PRTCP_SESSION)pTmp)->XmtSSRCList.prev;
if (pRRCM == NULL)
{
RRCM_DBG_MSG ("RCTP : ERROR - No RTCP Xmt list", 0,
__FILE__, __LINE__, DBG_ERROR);
IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTCPNoXmtList));
}
while (pTmp)
{
if (pRRCM->RTCPsd == RTCPsd)
break;
else
{
pTmp = pTmp->next;
if (pTmp)
{
pRRCM = (PSSRC_ENTRY)((PRTCP_SESSION)pTmp)->XmtSSRCList.prev;
}
continue;
}
}
if (pTmp == NULL)
{
RRCM_DBG_MSG ("RTCP: ERROR - Invalid RTCP session", 0,
__FILE__, __LINE__, DBG_ERROR);
IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTCPInvalidSession));
}
if (dwFilterFlags && (pFilterPattern == NULL))
{
RRCM_DBG_MSG ("RTCP: ERROR - Invalid RTCP FilterPattern is NULL", 0,
__FILE__, __LINE__, DBG_ERROR);
IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTCPInvalidRequest));
}
// go through the list of transmitters for this RTCP session
pRRCM = (PSSRC_ENTRY)((PRTCP_SESSION)pTmp)->XmtSSRCList.prev;
index = 0;
while (pRRCM && numEntriesInBfr)
{
// go to the desired offset
if (offset)
{
offset--;
pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
continue;
}
if (dwFilterFlags)
{
matched = FALSE;
switch (dwFilterFlags)
{
case FLTR_SSRC:
if(pRRCM->SSRC == *((DWORD *)pFilterPattern))
matched=TRUE;
break;
case FLTR_CNAME:
if((memcmp ((char *)pFilterPattern,
pRRCM->cnameInfo.sdesBfr,
dwFltrPtrnLen)) == 0)
matched = TRUE;
break;
default:
RRCM_DBG_MSG ("RTCP: ERROR - Invalid FilterFlag", 0,
__FILE__, __LINE__, DBG_ERROR);
IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTCPNotImpl));
}
if (!matched)
{
pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
continue;
}
else
numEntriesInBfr--;
}
else
numEntriesInBfr--;
// fill in the our active Sender report information
pReportBfr[index].status = LOCAL_SSRC_RPT;
pReportBfr[index].ssrc = pRRCM->SSRC;
// lock-out bytes update
EnterCriticalSection (&pRRCM->critSect);
pReportBfr[index].dwSrcNumPcktRealTime = pRRCM->xmtInfo.dwNumPcktSent;
pReportBfr[index].dwSrcNumByteRealTime = pRRCM->xmtInfo.dwNumBytesSent;
// release lock
LeaveCriticalSection (&pRRCM->critSect);
// a source - It's supposed to know it's own payload type
pReportBfr[index].PayLoadType = UNKNOWN_PAYLOAD_TYPE;
// our own sampling frequency
pReportBfr[index].dwStreamClock = pRRCM->dwStreamClock;
if (pRRCM->cnameInfo.dwSdesLength)
{
memcpy (pReportBfr[index].cname,
pRRCM->cnameInfo.sdesBfr,
pRRCM->cnameInfo.dwSdesLength);
pReportBfr[index].dwCnameLen = pRRCM->cnameInfo.dwSdesLength;
}
if (pRRCM->nameInfo.dwSdesLength)
{
memcpy (pReportBfr[index].name,
pRRCM->nameInfo.sdesBfr,
pRRCM->nameInfo.dwSdesLength);
pReportBfr[index].dwNameLen = pRRCM->nameInfo.dwSdesLength;
}
if (pRRCM->fromLen)
{
memcpy (&pReportBfr[index].fromAddr,
&pRRCM->from,
pRRCM->fromLen);
pReportBfr[index].dwFromLen = pRRCM->fromLen;
}
numEntryWritten++;
index++;
// go to next entry
pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
}
// go through the list of receivers for this RTCP session
pRRCM = (PSSRC_ENTRY)((PRTCP_SESSION)pTmp)->RcvSSRCList.prev;
while (pRRCM && numEntriesInBfr)
{
// go to the desired offset
if (offset)
{
offset--;
pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
continue;
}
if (dwFilterFlags)
{
matched = FALSE;
switch (dwFilterFlags)
{
case FLTR_SSRC:
if(pRRCM->SSRC == *((DWORD *)pFilterPattern))
matched=TRUE;
break;
case FLTR_CNAME:
if((memcmp ((char *)pFilterPattern,
pRRCM->cnameInfo.sdesBfr,
dwFltrPtrnLen)) == 0)
matched = TRUE;
break;
default:
RRCM_DBG_MSG ("RTCP: ERROR - Invalid FilterFlag", 0,
__FILE__, __LINE__, DBG_ERROR);
IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTCPNotImpl));
}
if (!matched)
{
pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
continue;
}
else
numEntriesInBfr--;
}
else
numEntriesInBfr--;
// fill in the Receiver report information
pReportBfr[index].ssrc = pRRCM->SSRC;
pReportBfr[index].status = REMOTE_SSRC_RPT;
// lock-out counters update
EnterCriticalSection (&pRRCM->critSect);
#ifdef ENABLE_FLOATING_POINT
pReportBfr[index].SrcJitter = pRRCM->rcvInfo.interJitter;
#else
// Check RFC for details of the round off
pReportBfr[index].SrcJitter = pRRCM->rcvInfo.interJitter >> 4;
#endif
pReportBfr[index].dwSrcXtndNum =
pRRCM->rcvInfo.XtendedSeqNum.seq_union.dwXtndedHighSeqNumRcvd;
// real time receive information
pReportBfr[index].dwSrcNumPcktRealTime = pRRCM->rcvInfo.dwNumPcktRcvd;
pReportBfr[index].dwSrcNumByteRealTime = pRRCM->rcvInfo.dwNumBytesRcvd;
// get sender information from Sender's RTCP report
pReportBfr[index].dwSrcNumPckt = pRRCM->xmtInfo.dwNumPcktSent;
pReportBfr[index].dwSrcNumByte = pRRCM->xmtInfo.dwNumBytesSent;
pReportBfr[index].dwSrcLsr = pRRCM->xmtInfo.dwLastSR;
pReportBfr[index].dwSrcNtpMsw = pRRCM->xmtInfo.dwNTPmsw;
pReportBfr[index].dwSrcNtpLsw = pRRCM->xmtInfo.dwNTPlsw;
pReportBfr[index].dwSrcRtpTs = pRRCM->xmtInfo.dwRTPts;
dwLost = getSSRCpcktLoss (pRRCM, FALSE);
// release lock
LeaveCriticalSection (&pRRCM->critSect);
// the last payload seen on this RTP stream
pReportBfr[index].PayLoadType = pRRCM->PayLoadType;
// last report received time
pReportBfr[index].dwLastReportRcvdTime = pRRCM->dwLastReportRcvdTime;
// fraction lost is in network byte order
pReportBfr[index].SrcFraction = (dwLost & 0xFF);
// cumulative lost is a 24 bits value in network byte order
RRCMws.ntohl (pRRCM->RTPsd, dwLost, &dwTmp);
dwTmp &= 0x00FFFFFF;
pReportBfr[index].SrcNumLost = dwTmp;
// get feedback information
if (pRRCM->rrFeedback.SSRC)
{
pReportBfr[index].status |= FEEDBACK_FOR_LOCAL_SSRC_PRESENT;
memcpy (&pReportBfr[index].feedback, &pRRCM->rrFeedback,
sizeof(RTCP_FEEDBACK));
}
if (pRRCM->cnameInfo.dwSdesLength)
{
memcpy (pReportBfr[index].cname,
pRRCM->cnameInfo.sdesBfr,
pRRCM->cnameInfo.dwSdesLength);
pReportBfr[index].dwCnameLen = pRRCM->cnameInfo.dwSdesLength;
}
if (pRRCM->nameInfo.dwSdesLength)
{
memcpy (pReportBfr[index].name,
pRRCM->nameInfo.sdesBfr,
pRRCM->nameInfo.dwSdesLength);
pReportBfr[index].dwNameLen = pRRCM->nameInfo.dwSdesLength;
}
if (pRRCM->fromLen)
{
memcpy (&pReportBfr[index].fromAddr,
&pRRCM->from,
pRRCM->fromLen);
pReportBfr[index].dwFromLen = pRRCM->fromLen;
}
numEntryWritten++;
index++;
// go to next entry
pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
}
// check to see if there are additional entries
if (pRRCM != NULL)
*moreEntries = TRUE;
*status = numEntryWritten;
IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
return (dwStatus);
}
/*----------------------------------------------------------------------------
* Function : getRtcpSessionList
* Description: Get a list of current RTCP session.
*
* Input : pSockBfr: -> to a socket buffer
* pNumEntries: -> to number of allocated entries in buffers.
* pNumUpdated: -> number of entries updated
*
* Return: OK: RRCM_NoError
* !0: Error code (see RRCM.H)
---------------------------------------------------------------------------*/
HRESULT WINAPI getRtcpSessionList (PDWORD_PTR pSockBfr,
DWORD dwNumEntries,
PDWORD pNumUpdated)
{
DWORD dwStatus = RRCM_NoError;
PRTCP_SESSION pRTCP;
PSSRC_ENTRY pSSRC;
IN_OUT_STR ("RTCP: Enter getRtpSessionList()\n");
// lock out session's access
EnterCriticalSection (&pRTCPContext->critSect);
*pNumUpdated = 0;
// look for the RTCP session
pRTCP = (PRTCP_SESSION)pRTCPContext->RTCPSession.prev;
if (pRTCP == NULL)
{
// Unlock out session's access
LeaveCriticalSection (&pRTCPContext->critSect);
IN_OUT_STR ("RTCP: Exit getRtpSessionList()\n");
return (MAKE_RRCM_ERROR (RRCMError_RTPNoSession));
}
// loop through the session's list
while (pRTCP)
{
pSSRC = (PSSRC_ENTRY)pRTCP->XmtSSRCList.prev;
if (pSSRC == NULL)
{
// Unlock out session's access
LeaveCriticalSection (&pRTCPContext->critSect);
RRCM_DBG_MSG ("RCTP : ERROR - No RTCP Xmt list", 0,
__FILE__, __LINE__, DBG_ERROR);
IN_OUT_STR ("RTCP: Exit getRtpSessionList()\n");
return (MAKE_RRCM_ERROR (RRCMError_RTCPNoXmtList));
}
if (dwNumEntries)
{
pSockBfr[*pNumUpdated] = pSSRC->RTCPsd;
*pNumUpdated += 1;
dwNumEntries --;
}
if (dwNumEntries == 0)
{
break;
}
// next entry
pRTCP = (PRTCP_SESSION)(pRTCP->RTCPList.next);
}
// Unlock out session's access
LeaveCriticalSection (&pRTCPContext->critSect);
IN_OUT_STR ("RTCP: Exit getRtpSessionList()\n");
return dwStatus;
}
// [EOF]