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