Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

774 lines
23 KiB

/*----------------------------------------------------------------------------
* File: RRCMMISC.C
* Product: RTP/RTCP implementation.
* Description: Provides common RTP/RTCP support functionality.
*
*
* 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
/--------------------------------------------------------------------------*/
#ifdef ENABLE_ISDM2
extern KEY_HANDLE hRRCMRootKey;
extern ISDM2 Isdm2;
#endif
extern RRCM_WS RRCMws;
#ifdef _DEBUG
extern char debug_string[];
#endif
#ifdef ISRDBG
extern WORD ghISRInst;
#endif
/*--------------------------------------------------------------------------
* Function : searchForMySSRC
* Description: Find the SSRC for this stream.
*
* Input : pSSRC : -> to the SSRC entry
* RTPSocket : RTP socket descriptor
*
* Return: NULL ==> Session not found.
* Buffer Address ==> OK, Session ptr returned
--------------------------------------------------------------------------*/
PSSRC_ENTRY searchForMySSRC(PSSRC_ENTRY pSSRC,
SOCKET RTPSocket)
{
PSSRC_ENTRY pRRCMSession;
IN_OUT_STR ("RTP : Enter searchForMySSRC()\n");
for (pRRCMSession = NULL;
(pSSRC != NULL);
pSSRC = (PSSRC_ENTRY)pSSRC->SSRCList.prev)
{
if (pSSRC->RTPsd == RTPSocket)
{
pRRCMSession = pSSRC;
break;
}
}
IN_OUT_STR ("RTP : Exit searchForMySSRC()\n");
return (pRRCMSession);
}
/*--------------------------------------------------------------------------
* Function : searchforSSRCatHead
* Description: Search through linked list of RTCP entries starting at the
* head of the list.
*
* Input : pSSRC : -> to the SSRC entry
* ssrc : ssrc to look for
*
* Return: NULL ==> Session not found.
* Non-NULL ==> OK, SSRC entry found
--------------------------------------------------------------------------*/
PSSRC_ENTRY searchforSSRCatHead(PSSRC_ENTRY pSSRC,
DWORD ssrc)
{
PSSRC_ENTRY pRRCMSession;
IN_OUT_STR ("RTP : Enter searchForMySSRCatHead()\n");
for (pRRCMSession = NULL;
(pSSRC != NULL) &&
(pRRCMSession == NULL) && (ssrc <= pSSRC->SSRC);
pSSRC = (PSSRC_ENTRY)pSSRC->SSRCList.prev)
{
if (pSSRC->SSRC == ssrc)
{
pRRCMSession = pSSRC;
}
}
IN_OUT_STR ("RTP : Exit searchForMySSRCatHead()\n");
return (pRRCMSession);
}
/*--------------------------------------------------------------------------
* Function : searchforSSRCatTail
* Description: Search through linked list of RTCP entries starting at the
* tail of the list.
*
* Input : pSSRC : -> to the SSRC entry
* ssrc : SSRC to look for
*
* Return: NULL ==> Session not found.
* Non-NULL ==> OK, SSRC entry found
--------------------------------------------------------------------------*/
PSSRC_ENTRY searchforSSRCatTail(PSSRC_ENTRY pSSRC,
DWORD ssrc)
{
PSSRC_ENTRY pRRCMSession;
IN_OUT_STR ("RTP : Enter searchForMySSRCatTail()\n");
for (pRRCMSession = NULL;
(pSSRC != NULL) &&
(pRRCMSession == NULL) && (ssrc >= pSSRC->SSRC);
pSSRC = (PSSRC_ENTRY)pSSRC->SSRCList.next)
{
if (pSSRC->SSRC == ssrc)
{
pRRCMSession = pSSRC;
}
}
IN_OUT_STR ("RTP : Exit searchForMySSRCatTail()\n");
return (pRRCMSession);
}
/*---------------------------------------------------------------------------
* Function : saveNetworkAddress
* Description: Saves the received or local network Address in the local
* context.
*
* Input : pSSRCEntry : -> to the SSRC entry
* pNetAddr : -> to the network address
* addrLen : Address length
*
* Return: OK: RRCM_NoError
--------------------------------------------------------------------------*/
DWORD saveNetworkAddress (PSSRC_ENTRY pSSRC,
PSOCKADDR pNetAddr,
int addrLen)
{
IN_OUT_STR ("RTP : Enter saveNetworkAddress()\n");
pSSRC->dwSSRCStatus |= NETWK_ADDR_UPDATED;
pSSRC->fromLen = addrLen;
memcpy (&pSSRC->from, pNetAddr, addrLen);
IN_OUT_STR ("RTP : Exit saveNetworkAddress()\n");
return RRCM_NoError;
}
/*---------------------------------------------------------------------------
* Function : updateRTCPDestinationAddress
* Description: The applicatino updates the RTCP destination address
*
* Input : hRTPSess : RTP session
* pAddr : -> to address structure of RTCP information
* addrLen : Address length
*
* Return: RRCM_NoError = OK.
* Otherwise(!=0) = Check RRCM.h file for references.
--------------------------------------------------------------------------*/
DWORD WINAPI updateRTCPDestinationAddress (HANDLE hRTPSess,
PSOCKADDR pRtcpAddr,
int addrLen)
{
PRTP_SESSION pRTPSession = (PRTP_SESSION) hRTPSess;
PRTCP_SESSION pRTCPses;
#ifdef ENABLE_ISDM2
PSSRC_ENTRY pSSRC;
#endif
IN_OUT_STR ("RTP : Enter updateRTCPDestinationAddress()\n");
if (pRTPSession == NULL)
{
RRCM_DBG_MSG ("RTP : ERROR - Invalid RTP session", 0,
__FILE__, __LINE__, DBG_CRITICAL);
IN_OUT_STR ("RTP : Exit updateRTCPDestinationAddress()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTPInvalidSession));
}
// get the RTCP session
pRTCPses = pRTPSession->pRTCPSession;
if (pRTCPses == NULL)
{
RRCM_DBG_MSG ("RTP : ERROR - Invalid RTCP session", 0,
__FILE__, __LINE__, DBG_CRITICAL);
IN_OUT_STR ("RTP : Exit updateRTCPDestinationAddress()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTCPInvalidSession));
}
if (!(pRTCPses->dwSessionStatus & RTCP_DEST_LEARNED))
{
pRTCPses->dwSessionStatus |= RTCP_DEST_LEARNED;
pRTCPses->toLen = addrLen;
memcpy (&pRTCPses->toBfr, pRtcpAddr, addrLen);
// register our Xmt SSRC - Rcvd one will be found later
#ifdef ENABLE_ISDM2
if (Isdm2.hISDMdll)
{
pSSRC = (PSSRC_ENTRY)pRTCPses->XmtSSRCList.prev;
if (pSSRC != NULL)
registerSessionToISDM (pSSRC, pRTCPses, &Isdm2);
}
#endif
}
IN_OUT_STR ("RTP : Exit updateRTCPDestinationAddress()\n");
return RRCM_NoError;
}
/*---------------------------------------------------------------------------
* Function : updateSSRCentry
* Description: The application updates some of the SSRC information
*
* Input : RTPsd : RTP socket descriptor
* updateType : Type of update desired
* updateInfo : Update information
* misc : Miscelleanous information
*
* Return: RRCM_NoError = OK.
* Otherwise(!=0) = Check RRCM.h file for references.
--------------------------------------------------------------------------*/
HRESULT WINAPI updateSSRCentry ( HANDLE hRTPSess,
SOCKET RTPsd,
DWORD updateType,
DWORD_PTR updateInfo,
DWORD_PTR misc)
{
PRTP_SESSION pRTPSession = (PRTP_SESSION) hRTPSess;
PRTCP_SESSION pRTCPses;
PSSRC_ENTRY pSSRC;
PLINK_LIST pTmp;
PSDES_DATA pSdes;
IN_OUT_STR ("RTP : Enter updateRTCPSdes ()\n");
if (pRTPSession == NULL)
{
RRCM_DBG_MSG ("RTP : ERROR - Invalid RTP session", 0,
__FILE__, __LINE__, DBG_CRITICAL);
IN_OUT_STR ("RTP : Exit updateRTCPSdes ()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTPInvalidSession));
}
// get the RTCP session
pRTCPses = pRTPSession->pRTCPSession;
if (pRTCPses == NULL)
{
RRCM_DBG_MSG ("RTP : ERROR - Invalid RTCP session", 0,
__FILE__, __LINE__, DBG_CRITICAL);
IN_OUT_STR ("RTP : Exit updateRTCPSdes ()\n");
return (MAKE_RRCM_ERROR(RRCMError_RTCPInvalidSession));
}
// search for the socket descriptor (unique per session)
// walk through the list from the tail
pTmp = (PLINK_LIST)pRTCPses->XmtSSRCList.prev;
while (pTmp)
{
if (((PSSRC_ENTRY)pTmp)->RTPsd == RTPsd)
{
// lock access to this entry
EnterCriticalSection (&((PSSRC_ENTRY)pTmp)->critSect);
pSSRC = (PSSRC_ENTRY)pTmp;
switch (updateType)
{
case RRCM_UPDATE_SDES:
// update the SDES
pSdes = (PSDES_DATA)updateInfo;
switch (pSdes->dwSdesType)
{
case RTCP_SDES_CNAME:
pSSRC->cnameInfo.dwSdesLength = pSdes->dwSdesLength;
memcpy (pSSRC->cnameInfo.sdesBfr, pSdes->sdesBfr,
pSdes->dwSdesLength);
pSSRC->cnameInfo.dwSdesFrequency =
frequencyToPckt (pSdes->dwSdesFrequency);
pSSRC->cnameInfo.dwSdesEncrypted = pSdes->dwSdesEncrypted;
break;
case RTCP_SDES_NAME:
pSSRC->nameInfo.dwSdesLength = pSdes->dwSdesLength;
memcpy (pSSRC->nameInfo.sdesBfr, pSdes->sdesBfr,
pSdes->dwSdesLength);
pSSRC->nameInfo.dwSdesFrequency =
frequencyToPckt (pSdes->dwSdesFrequency);
pSSRC->nameInfo.dwSdesEncrypted = pSdes->dwSdesEncrypted;
break;
case RTCP_SDES_EMAIL:
pSSRC->emailInfo.dwSdesLength = pSdes->dwSdesLength;
memcpy (pSSRC->emailInfo.sdesBfr, pSdes->sdesBfr,
pSdes->dwSdesLength);
pSSRC->emailInfo.dwSdesFrequency =
frequencyToPckt (pSdes->dwSdesFrequency);
pSSRC->emailInfo.dwSdesEncrypted = pSdes->dwSdesEncrypted;
break;
case RTCP_SDES_PHONE:
pSSRC->phoneInfo.dwSdesLength = pSdes->dwSdesLength;
memcpy (pSSRC->phoneInfo.sdesBfr, pSdes->sdesBfr,
pSdes->dwSdesLength);
pSSRC->phoneInfo.dwSdesFrequency =
frequencyToPckt (pSdes->dwSdesFrequency);
pSSRC->phoneInfo.dwSdesEncrypted = pSdes->dwSdesEncrypted;
break;
case RTCP_SDES_LOC:
pSSRC->locInfo.dwSdesLength = pSdes->dwSdesLength;
memcpy (pSSRC->locInfo.sdesBfr, pSdes->sdesBfr,
pSdes->dwSdesLength);
pSSRC->locInfo.dwSdesFrequency =
frequencyToPckt (pSdes->dwSdesFrequency);
pSSRC->locInfo.dwSdesEncrypted = pSdes->dwSdesEncrypted;
break;
case RTCP_SDES_TOOL:
pSSRC->toolInfo.dwSdesLength = pSdes->dwSdesLength;
memcpy (pSSRC->toolInfo.sdesBfr, pSdes->sdesBfr,
pSdes->dwSdesLength);
pSSRC->toolInfo.dwSdesFrequency =
frequencyToPckt (pSdes->dwSdesFrequency);
pSSRC->toolInfo.dwSdesEncrypted = pSdes->dwSdesEncrypted;
break;
case RTCP_SDES_TXT:
pSSRC->txtInfo.dwSdesLength = pSdes->dwSdesLength;
memcpy (pSSRC->txtInfo.sdesBfr, pSdes->sdesBfr,
pSdes->dwSdesLength);
pSSRC->txtInfo.dwSdesFrequency =
frequencyToPckt (pSdes->dwSdesFrequency);
pSSRC->txtInfo.dwSdesEncrypted = pSdes->dwSdesEncrypted;
break;
case RTCP_SDES_PRIV:
pSSRC->privInfo.dwSdesLength = pSdes->dwSdesLength;
memcpy (pSSRC->privInfo.sdesBfr, pSdes->sdesBfr,
pSdes->dwSdesLength);
pSSRC->privInfo.dwSdesFrequency =
frequencyToPckt (pSdes->dwSdesFrequency);
pSSRC->privInfo.dwSdesEncrypted = pSdes->dwSdesEncrypted;
break;
}
break;
case RRCM_UPDATE_STREAM_FREQUENCY:
// upate the stream clocking frequency
pSSRC->dwStreamClock = (DWORD)updateInfo;
break;
case RRCM_UPDATE_RTCP_STREAM_MIN_BW:
// upate the stream clocking frequency
pSSRC->xmtInfo.dwRtcpStreamMinBW = (DWORD)updateInfo;
break;
case RRCM_UPDATE_CALLBACK:
// update the callback information
EnterCriticalSection (&pRTCPses->critSect);
pRTCPses->pRRCMcallback = (PRRCM_EVENT_CALLBACK)updateInfo;
pRTCPses->dwCallbackUserInfo = misc;
LeaveCriticalSection (&pRTCPses->critSect);
break;
}
// unlock access to this entry
LeaveCriticalSection (&((PSSRC_ENTRY)pTmp)->critSect);
}
pTmp = pTmp->next;
}
IN_OUT_STR ("RTP : Exit updateRTCPSdes ()\n");
return RRCM_NoError;
}
/*---------------------------------------------------------------------------
* Function : RRCMnotification
* Description: Notify the application that one of the RTP/RTCP events that
* we keep track of has occured.
*
* Input : RRCMevent : RRCM event to report
* pSSRC : -> to the SSRC entry
* ssrc : SSRC which generated the event
* misc : Miscelleanous value
*
* Return: OK: RRCM_NoError
--------------------------------------------------------------------------*/
void RRCMnotification (RRCM_EVENT_T RRCMevent,
PSSRC_ENTRY pSSRC,
DWORD dwSSRC,
DWORD misc)
{
IN_OUT_STR ("RRCM: Enter RRCMnotification()\n");
// check to see if the application is interested by the RRCM event
if (pSSRC->pRTCPses->pRRCMcallback == NULL)
return;
switch (RRCMevent)
{
case RRCM_NEW_SOURCE_EVENT:
pSSRC->pRTCPses->pRRCMcallback (RRCMevent, dwSSRC, misc,
pSSRC->pRTCPses->dwCallbackUserInfo);
break;
case RRCM_LOCAL_COLLISION_EVENT:
pSSRC->pRTCPses->pRRCMcallback (RRCMevent, pSSRC->SSRC, dwSSRC,
pSSRC->pRTCPses->dwCallbackUserInfo);
break;
case RRCM_REMOTE_COLLISION_EVENT:
pSSRC->pRTCPses->pRRCMcallback (RRCMevent, dwSSRC, 0,
pSSRC->pRTCPses->dwCallbackUserInfo);
break;
case RRCM_RECV_RTCP_SNDR_REPORT_EVENT:
pSSRC->pRTCPses->pRRCMcallback (RRCMevent, dwSSRC, pSSRC->RTCPsd,
pSSRC->pRTCPses->dwCallbackUserInfo);
break;
case RRCM_RECV_RTCP_RECV_REPORT_EVENT:
pSSRC->pRTCPses->pRRCMcallback (RRCMevent, dwSSRC, pSSRC->RTCPsd,
pSSRC->pRTCPses->dwCallbackUserInfo);
break;
case RRCM_TIMEOUT_EVENT:
pSSRC->pRTCPses->pRRCMcallback (RRCMevent, dwSSRC, 0,
pSSRC->pRTCPses->dwCallbackUserInfo);
break;
case RRCM_BYE_EVENT:
pSSRC->pRTCPses->pRRCMcallback (RRCMevent, dwSSRC, 0,
pSSRC->pRTCPses->dwCallbackUserInfo);
break;
case RRCM_RTCP_WS_RCV_ERROR:
pSSRC->pRTCPses->pRRCMcallback (RRCMevent, dwSSRC, misc,
pSSRC->pRTCPses->dwCallbackUserInfo);
break;
case RRCM_RTCP_WS_XMT_ERROR:
pSSRC->pRTCPses->pRRCMcallback (RRCMevent, dwSSRC, misc,
pSSRC->pRTCPses->dwCallbackUserInfo);
break;
default:
break;
}
IN_OUT_STR ("RRCM: Exit RRCMnotification()\n");
}
/*----------------------------------------------------------------------------
* Function : registerSessionToISDM
* Description: Register an RTP/RTCP session with ISDM
*
* Input : pSSRC : -> to the SSRC's entry
* pRTCP : -> to the RTCP session's information
* pIsdm : -> to the ISDM information
*
* Return: None
---------------------------------------------------------------------------*/
#ifdef ENABLE_ISDM2
#define SESSION_BFR_SIZE 30
void registerSessionToISDM (PSSRC_ENTRY pSSRC,
PRTCP_SESSION pRTCPses,
PISDM2 pIsdm2)
{
struct sockaddr_in *pSSRCadr;
unsigned short port;
unsigned long netAddr;
CHAR SsrcBfr[10];
CHAR sessionBfr[SESSION_BFR_SIZE];
unsigned char *ptr;
int num;
HRESULT hError;
ISDM2_ENTRY Isdm2Stat;
// get the destination address as the session identifier
pSSRCadr = (struct sockaddr_in *)&pRTCPses->toBfr;
RRCMws.htons (pSSRC->RTPsd, pSSRCadr->sin_port, &port);
netAddr = pSSRCadr->sin_addr.S_un.S_addr;
ptr = (unsigned char *)&netAddr;
memset (sessionBfr, 0x00, SESSION_BFR_SIZE);
num = (int)*ptr++;
RRCMitoa (num, sessionBfr, 10);
strcat (sessionBfr, ".");
num = (int)*ptr++;
RRCMitoa (num, (sessionBfr + strlen(sessionBfr)), 10);
strcat (sessionBfr, ".");
num = (int)*ptr++;
RRCMitoa (num, (sessionBfr + strlen(sessionBfr)), 10);
strcat (sessionBfr, ".");
num = (int)*ptr;
RRCMitoa (num, (sessionBfr + strlen(sessionBfr)), 10);
strcat (sessionBfr, ".");
RRCMitoa (port, (sessionBfr + strlen(sessionBfr)), 10);
// get the SSRC
RRCMultoa (pSSRC->SSRC, SsrcBfr, 16);
// register the session
if (pRTCPses->hSessKey == NULL)
{
hError = Isdm2.ISDMEntry.ISD_CreateKey (hRRCMRootKey,
sessionBfr,
&pRTCPses->hSessKey);
if(FAILED(hError))
RRCM_DBG_MSG ("RTP: ISD_CreateKey Failed",0, NULL, 0, DBG_NOTIFY);
}
memset(&Isdm2Stat, 0x00, sizeof(ISDM2_ENTRY));
hError = Isdm2.ISDMEntry.ISD_CreateValue (pRTCPses->hSessKey,
SsrcBfr,
BINARY_VALUE,
(BYTE *)&Isdm2Stat,
sizeof(ISDM2_ENTRY),
&pSSRC->hISDM);
if(FAILED(hError))
RRCM_DBG_MSG ("RTP: ISD_CreateValue Failed",0, NULL, 0, DBG_NOTIFY);
}
/*----------------------------------------------------------------------------
* Function : udpateISDMsta
* Description: Update an ISDM data structure
*
* Input : pSSRC : -> to the SSRC's entry
* pIsdm : -> to the ISDM entry
* flag : Sender/Receive flag
* LocalFB : do or dont't update the local feedback
*
* Return: None
---------------------------------------------------------------------------*/
void updateISDMstat (PSSRC_ENTRY pSSRC,
PISDM2 pIsdm2,
DWORD flag,
BOOL LocalFB)
{
DWORD curTime = timeGetTime();
DWORD dwTmp;
DWORD dwValue;
ISDM2_ENTRY Isdm2Stat;
HRESULT hError;
unsigned short idx = 0;
EnterCriticalSection (&pIsdm2->critSect);
Isdm2Stat.SSRC = pSSRC->SSRC;
Isdm2Stat.PayLoadType = pSSRC->PayLoadType;
if (flag == RECVR)
{
Isdm2Stat.dwSSRCStatus = RECVR;
Isdm2Stat.rcvInfo.dwNumPcktRcvd = pSSRC->rcvInfo.dwNumPcktRcvd;
Isdm2Stat.rcvInfo.dwPrvNumPcktRcvd = pSSRC->rcvInfo.dwPrvNumPcktRcvd;
Isdm2Stat.rcvInfo.dwExpectedPrior = pSSRC->rcvInfo.dwExpectedPrior;
Isdm2Stat.rcvInfo.dwNumBytesRcvd = pSSRC->rcvInfo.dwNumBytesRcvd;
Isdm2Stat.rcvInfo.dwBaseRcvSeqNum = pSSRC->rcvInfo.dwBaseRcvSeqNum;
Isdm2Stat.rcvInfo.dwBadSeqNum = pSSRC->rcvInfo.dwBadSeqNum;
Isdm2Stat.rcvInfo.dwProbation = pSSRC->rcvInfo.dwProbation;
Isdm2Stat.rcvInfo.dwPropagationTime= pSSRC->rcvInfo.dwPropagationTime;
Isdm2Stat.rcvInfo.interJitter = pSSRC->rcvInfo.interJitter;
Isdm2Stat.rcvInfo.XtendedSeqNum.seq_union.dwXtndedHighSeqNumRcvd =
pSSRC->rcvInfo.XtendedSeqNum.seq_union.dwXtndedHighSeqNumRcvd;
}
else // (flag == ISDM_UPDATE_XMTSTAT)
{
Isdm2Stat.dwSSRCStatus = XMITR;
Isdm2Stat.xmitinfo.dwNumPcktSent = pSSRC->xmtInfo.dwNumPcktSent;
Isdm2Stat.xmitinfo.dwNumBytesSent = pSSRC->xmtInfo.dwNumBytesSent;
Isdm2Stat.xmitinfo.dwNTPmsw = pSSRC->xmtInfo.dwNTPmsw;
Isdm2Stat.xmitinfo.dwNTPlsw = pSSRC->xmtInfo.dwNTPlsw;
Isdm2Stat.xmitinfo.dwRTPts = pSSRC->xmtInfo.dwRTPts;
Isdm2Stat.xmitinfo.dwCurXmtSeqNum = pSSRC->xmtInfo.dwCurXmtSeqNum;
Isdm2Stat.xmitinfo.dwPrvXmtSeqNum = pSSRC->xmtInfo.dwPrvXmtSeqNum;
Isdm2Stat.xmitinfo.sessionBW = pSSRC->xmtInfo.dwRtcpStreamMinBW;
Isdm2Stat.xmitinfo.dwLastSR = pSSRC->xmtInfo.dwLastSR;
Isdm2Stat.xmitinfo.dwLastSRLocalTime =
pSSRC->xmtInfo.dwLastSRLocalTime;
Isdm2Stat.xmitinfo.dwLastSendRTPSystemTime =
pSSRC->xmtInfo.dwLastSendRTPSystemTime;
Isdm2Stat.xmitinfo.dwLastSendRTPTimeStamp =
pSSRC->xmtInfo.dwLastSendRTPTimeStamp;
}
if(LocalFB)
{
memcpy(&Isdm2Stat.rrFeedback, &pSSRC->rrFeedback, sizeof(RTCP_FEEDBACK));
}
else
{
Isdm2Stat.rrFeedback.SSRC = pSSRC->rrFeedback.SSRC;
#ifdef ENABLE_FLOATING_POINT
Isdm2Stat.rrFeedback.dwInterJitter = pSSRC->rcvInfo.interJitter;
#else
// Check RFC for details of the round off
Isdm2Stat.rrFeedback.dwInterJitter = pSSRC->rcvInfo.interJitter >> 4;
#endif
Isdm2Stat.rrFeedback.XtendedSeqNum.seq_union.dwXtndedHighSeqNumRcvd =
pSSRC->rcvInfo.XtendedSeqNum.seq_union.dwXtndedHighSeqNumRcvd;
// fraction/cumulative number lost are in network order
dwTmp = getSSRCpcktLoss (pSSRC, FALSE);
Isdm2Stat.rrFeedback.fractionLost = (dwTmp & 0xFF);
RRCMws.ntohl (pSSRC->RTPsd, dwTmp, &dwValue);
Isdm2Stat.rrFeedback.cumNumPcktLost = (dwValue & 0x00FFFFFF);
Isdm2Stat.rrFeedback.dwLastRcvRpt = pSSRC->rrFeedback.dwLastRcvRpt;
Isdm2Stat.rrFeedback.dwLastSR = pSSRC->xmtInfo.dwLastSR;
Isdm2Stat.rrFeedback.dwDelaySinceLastSR = getDLSR (pSSRC);
}
Isdm2Stat.dwLastReportRcvdTime = pSSRC->dwLastReportRcvdTime;
memcpy(&Isdm2Stat.cnameInfo, &pSSRC->cnameInfo, sizeof(SDES_DATA));
memcpy(&Isdm2Stat.nameInfo, &pSSRC->nameInfo, sizeof(SDES_DATA));
memcpy(&Isdm2Stat.from, &pSSRC->from, sizeof(SOCKADDR));
Isdm2Stat.fromLen = pSSRC->fromLen;
Isdm2Stat.dwNumRptSent = pSSRC->dwNumRptSent;
Isdm2Stat.dwNumRptRcvd = pSSRC->dwNumRptRcvd;
Isdm2Stat.dwNumXmtIoPending = pSSRC->dwNumXmtIoPending;
Isdm2Stat.dwStreamClock = pSSRC->dwStreamClock;
hError = Isdm2.ISDMEntry.ISD_SetValue (NULL,
pSSRC->hISDM,
NULL,
BINARY_VALUE,
(BYTE *)&Isdm2Stat,
sizeof(ISDM2_ENTRY));
if(FAILED(hError))
RRCM_DBG_MSG ("RTP: ISD_SetValue Failed",0, NULL, 0, DBG_NOTIFY);
LeaveCriticalSection (&pIsdm2->critSect);
}
#endif // #ifdef ENABLE_ISDM2
/*---------------------------------------------------------------------------
* Function : RRCMdebugMsg
* Description: Output RRCM debug messages
*
* Input : pMsg: -> to message
* err: Error code
* pFile: -> to file where the error occured
* line: Line number where the error occured
*
* Return: None
--------------------------------------------------------------------------*/
void RRCMdebugMsg (PCHAR pMsg,
DWORD err,
PCHAR pFile,
DWORD line,
DWORD type)
{
#ifdef ISRDBG
wsprintf (debug_string, "%s", pMsg);
if (err)
wsprintf (debug_string+strlen(debug_string), " Error:%d", err);
if (pFile != NULL)
wsprintf (debug_string+strlen(debug_string), " - %s, line:%d",
pFile, line);
switch (type)
{
case DBG_NOTIFY:
ISRNOTIFY(ghISRInst, debug_string, 0);
break;
case DBG_TRACE:
ISRTRACE(ghISRInst, debug_string, 0);
break;
case DBG_ERROR:
ISRERROR(ghISRInst, debug_string, 0);
break;
case DBG_WARNING:
ISRWARNING(ghISRInst, debug_string, 0);
break;
case DBG_TEMP:
ISRTEMP(ghISRInst, debug_string, 0);
break;
case DBG_CRITICAL:
ISRCRITICAL(ghISRInst, debug_string, 0);
break;
default:
break;
}
#elif DEBUG
extern HDBGZONE ghDbgZoneRRCM ;
lstrcpyn(debug_string, pMsg, DBG_STRING_LEN);
if (err)
wsprintf (debug_string+strlen(debug_string), " Error:%d", err);
if (pFile != NULL)
wsprintf (debug_string+strlen(debug_string), " - %s, line:%d",
pFile, line);
switch (type)
{
case DBG_NOTIFY:
case DBG_TRACE:
case DBG_WARNING:
case DBG_TEMP:
DBGMSG(ghDbgZoneRRCM,0,(debug_string)); // Trace Zone
break;
case DBG_ERROR:
case DBG_CRITICAL:
DBGMSG(ghDbgZoneRRCM,1,(debug_string)); // Error Zone
break;
default:
break;
}
#endif
}
// [EOF]