186 lines
5.5 KiB
C++
186 lines
5.5 KiB
C++
/*----------------------------------------------------------------------------
|
|
* File: RTPSEND.C
|
|
* Product: RTP/RTCP implementation
|
|
* Description: Provides WSA Send functions.
|
|
*
|
|
* This listing is supplied under the terms
|
|
* of a license agreement with Intel Corporation and
|
|
* many 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 PRTP_CONTEXT pRTPContext;
|
|
extern RRCM_WS RRCMws;
|
|
|
|
|
|
#if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
|
|
//INTEROP
|
|
extern LPInteropLogger RTPLogger;
|
|
#endif
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Function : RTPSendTo
|
|
* Description: Intercepts sendto requests from the application.
|
|
* Handles any statistical processing required for RTCP.
|
|
* Copies completion routine from app and substitutes its own.
|
|
* Apps completion routine will be called after RTP's completion
|
|
* routine gets called by Winsock2.
|
|
*
|
|
* Input : RTPsocket: RTP socket descriptor
|
|
* pBufs: -> to WSAbuf structure
|
|
* dwBufCount: Buffer count in WSAbuf structure
|
|
* pNumBytesSent: -> to number of bytes sent
|
|
* socketFlags: Flags
|
|
* pTo: -> to the destination address
|
|
* toLen: Destination address length
|
|
* pOverlapped: -> to overlapped I/O structure
|
|
* pCompletionRoutine: -> to completion routine
|
|
*
|
|
* Return: RRCM_NoError = OK.
|
|
* Otherwise(!=0) = Check RRCM.h file for references.
|
|
---------------------------------------------------------------------------*/
|
|
DWORD WINAPI RTPSendTo (
|
|
HANDLE hRTPSess,
|
|
SOCKET RTPsocket,
|
|
LPWSABUF pBufs,
|
|
DWORD dwBufCount,
|
|
LPDWORD pNumBytesSent,
|
|
int socketFlags,
|
|
LPVOID pTo,
|
|
int toLen,
|
|
LPWSAOVERLAPPED pOverlapped,
|
|
LPWSAOVERLAPPED_COMPLETION_ROUTINE pCompletionRoutine)
|
|
{
|
|
int dwStatus;
|
|
int dwErrorStatus;
|
|
PRTP_SESSION pRTPSession = (PRTP_SESSION) hRTPSess;
|
|
RTP_HDR_T *pRTPHeader;
|
|
PSSRC_ENTRY pSSRC;
|
|
|
|
IN_OUT_STR ("RTP : Enter RTPSendTo()\n");
|
|
|
|
// If RTP context doesn't exist, report error and return.
|
|
if (pRTPContext == NULL)
|
|
{
|
|
RRCM_DBG_MSG ("RTP : ERROR - No RTP Instance", 0,
|
|
__FILE__, __LINE__, DBG_CRITICAL);
|
|
IN_OUT_STR ("RTP : Exit RTPSendTo()\n");
|
|
|
|
return (MAKE_RRCM_ERROR(RRCMError_RTPInvalid));
|
|
}
|
|
|
|
ASSERT(pRTPSession);
|
|
|
|
// Complete filling in header. First cast a pointer
|
|
// of type RTP_HDR_T to ease accessing
|
|
pRTPHeader = (RTP_HDR_T *)pBufs->buf;
|
|
ASSERT (pRTPHeader);
|
|
|
|
// Now setup some of the RTP header fields
|
|
pRTPHeader->type = RTP_TYPE; // RTP Version 2
|
|
|
|
// Get pointer to our entry in SSRC table for this session
|
|
pSSRC = searchForMySSRC (
|
|
(PSSRC_ENTRY)pRTPSession->pRTCPSession->XmtSSRCList.prev,
|
|
RTPsocket);
|
|
ASSERT (pSSRC);
|
|
|
|
// lock out access to this RTCP session variable
|
|
EnterCriticalSection (&pSSRC->critSect);
|
|
|
|
// save the RTP timestamp
|
|
RRCMws.ntohl (RTPsocket, pRTPHeader->ts,
|
|
&pSSRC->xmtInfo.dwLastSendRTPTimeStamp);
|
|
|
|
// save the last transmit time
|
|
pSSRC->xmtInfo.dwLastSendRTPSystemTime = timeGetTime ();
|
|
|
|
// copy over sequence number sent
|
|
RRCMws.ntohs (RTPsocket, pRTPHeader->seq,
|
|
(WORD *)&pSSRC->xmtInfo.dwCurXmtSeqNum);
|
|
|
|
// SSRC
|
|
RRCMws.htonl (RTPsocket, pSSRC->SSRC, &pRTPHeader->ssrc);
|
|
|
|
// Update initial XmtSeqNum so RTCP knows the baseline
|
|
if ((pSSRC->dwSSRCStatus & SEQ_NUM_UPDATED) == 0)
|
|
{
|
|
pSSRC->xmtInfo.dwPrvXmtSeqNum = pSSRC->xmtInfo.dwCurXmtSeqNum;
|
|
pSSRC->dwSSRCStatus |= SEQ_NUM_UPDATED;
|
|
}
|
|
|
|
// update the payload type for this SSRC_ENTRY
|
|
pSSRC->PayLoadType = pRTPHeader->pt;
|
|
|
|
// unlock pointer access
|
|
LeaveCriticalSection (&pSSRC->critSect);
|
|
|
|
#if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
|
|
if (RTPLogger)
|
|
{
|
|
//INTEROP
|
|
InteropOutput (RTPLogger,
|
|
(BYTE FAR*)(pBufs->buf),
|
|
(int)pBufs->len,
|
|
RTPLOG_SENT_PDU | RTP_PDU);
|
|
}
|
|
#endif
|
|
|
|
dwStatus = RRCMws.sendTo (RTPsocket,
|
|
pBufs,
|
|
dwBufCount,
|
|
pNumBytesSent,
|
|
socketFlags,
|
|
(PSOCKADDR)pTo,
|
|
toLen,
|
|
pOverlapped,
|
|
pCompletionRoutine);
|
|
|
|
|
|
if (dwStatus != SOCKET_ERROR || GetLastError() == WSA_IO_PENDING)
|
|
{
|
|
DWORD i, cbTransferred = 0;
|
|
// assume the send will succeed
|
|
/* lock out access to this RTCP session variable */
|
|
EnterCriticalSection (&pSSRC->critSect);
|
|
|
|
// calculate statistics (-DWORD) for the CRSC entry defined
|
|
// in the RTP header (but we should remove it from the data structure)
|
|
for (i = 0;i < dwBufCount; i++)
|
|
cbTransferred += pBufs[i].len;
|
|
|
|
pSSRC->xmtInfo.dwNumBytesSent += (cbTransferred -
|
|
(sizeof(RTP_HDR_T) - sizeof(DWORD)));
|
|
|
|
pSSRC->xmtInfo.dwNumPcktSent++;
|
|
|
|
/* unlock access */
|
|
LeaveCriticalSection (&pSSRC->critSect);
|
|
}
|
|
|
|
IN_OUT_STR ("RTP : Exit RTPSendTo()\n");
|
|
|
|
return (dwStatus);
|
|
}
|
|
|
|
|
|
|
|
|
|
// [EOF]
|
|
|