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
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]
|
|
|