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.

185 lines
5.5 KiB

  1. /*----------------------------------------------------------------------------
  2. * File: RTPSEND.C
  3. * Product: RTP/RTCP implementation
  4. * Description: Provides WSA Send functions.
  5. *
  6. * This listing is supplied under the terms
  7. * of a license agreement with Intel Corporation and
  8. * many not be copied nor disclosed except in accordance
  9. * with the terms of that agreement.
  10. * Copyright (c) 1995 Intel Corporation.
  11. *--------------------------------------------------------------------------*/
  12. #include "rrcm.h"
  13. /*---------------------------------------------------------------------------
  14. / Global Variables
  15. /--------------------------------------------------------------------------*/
  16. /*---------------------------------------------------------------------------
  17. / External Variables
  18. /--------------------------------------------------------------------------*/
  19. extern PRTP_CONTEXT pRTPContext;
  20. extern RRCM_WS RRCMws;
  21. #if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
  22. //INTEROP
  23. extern LPInteropLogger RTPLogger;
  24. #endif
  25. /*----------------------------------------------------------------------------
  26. * Function : RTPSendTo
  27. * Description: Intercepts sendto requests from the application.
  28. * Handles any statistical processing required for RTCP.
  29. * Copies completion routine from app and substitutes its own.
  30. * Apps completion routine will be called after RTP's completion
  31. * routine gets called by Winsock2.
  32. *
  33. * Input : RTPsocket: RTP socket descriptor
  34. * pBufs: -> to WSAbuf structure
  35. * dwBufCount: Buffer count in WSAbuf structure
  36. * pNumBytesSent: -> to number of bytes sent
  37. * socketFlags: Flags
  38. * pTo: -> to the destination address
  39. * toLen: Destination address length
  40. * pOverlapped: -> to overlapped I/O structure
  41. * pCompletionRoutine: -> to completion routine
  42. *
  43. * Return: RRCM_NoError = OK.
  44. * Otherwise(!=0) = Check RRCM.h file for references.
  45. ---------------------------------------------------------------------------*/
  46. DWORD WINAPI RTPSendTo (
  47. HANDLE hRTPSess,
  48. SOCKET RTPsocket,
  49. LPWSABUF pBufs,
  50. DWORD dwBufCount,
  51. LPDWORD pNumBytesSent,
  52. int socketFlags,
  53. LPVOID pTo,
  54. int toLen,
  55. LPWSAOVERLAPPED pOverlapped,
  56. LPWSAOVERLAPPED_COMPLETION_ROUTINE pCompletionRoutine)
  57. {
  58. int dwStatus;
  59. int dwErrorStatus;
  60. PRTP_SESSION pRTPSession = (PRTP_SESSION) hRTPSess;
  61. RTP_HDR_T *pRTPHeader;
  62. PSSRC_ENTRY pSSRC;
  63. IN_OUT_STR ("RTP : Enter RTPSendTo()\n");
  64. // If RTP context doesn't exist, report error and return.
  65. if (pRTPContext == NULL)
  66. {
  67. RRCM_DBG_MSG ("RTP : ERROR - No RTP Instance", 0,
  68. __FILE__, __LINE__, DBG_CRITICAL);
  69. IN_OUT_STR ("RTP : Exit RTPSendTo()\n");
  70. return (MAKE_RRCM_ERROR(RRCMError_RTPInvalid));
  71. }
  72. ASSERT(pRTPSession);
  73. // Complete filling in header. First cast a pointer
  74. // of type RTP_HDR_T to ease accessing
  75. pRTPHeader = (RTP_HDR_T *)pBufs->buf;
  76. ASSERT (pRTPHeader);
  77. // Now setup some of the RTP header fields
  78. pRTPHeader->type = RTP_TYPE; // RTP Version 2
  79. // Get pointer to our entry in SSRC table for this session
  80. pSSRC = searchForMySSRC (
  81. (PSSRC_ENTRY)pRTPSession->pRTCPSession->XmtSSRCList.prev,
  82. RTPsocket);
  83. ASSERT (pSSRC);
  84. // lock out access to this RTCP session variable
  85. EnterCriticalSection (&pSSRC->critSect);
  86. // save the RTP timestamp
  87. RRCMws.ntohl (RTPsocket, pRTPHeader->ts,
  88. &pSSRC->xmtInfo.dwLastSendRTPTimeStamp);
  89. // save the last transmit time
  90. pSSRC->xmtInfo.dwLastSendRTPSystemTime = timeGetTime ();
  91. // copy over sequence number sent
  92. RRCMws.ntohs (RTPsocket, pRTPHeader->seq,
  93. (WORD *)&pSSRC->xmtInfo.dwCurXmtSeqNum);
  94. // SSRC
  95. RRCMws.htonl (RTPsocket, pSSRC->SSRC, &pRTPHeader->ssrc);
  96. // Update initial XmtSeqNum so RTCP knows the baseline
  97. if ((pSSRC->dwSSRCStatus & SEQ_NUM_UPDATED) == 0)
  98. {
  99. pSSRC->xmtInfo.dwPrvXmtSeqNum = pSSRC->xmtInfo.dwCurXmtSeqNum;
  100. pSSRC->dwSSRCStatus |= SEQ_NUM_UPDATED;
  101. }
  102. // update the payload type for this SSRC_ENTRY
  103. pSSRC->PayLoadType = pRTPHeader->pt;
  104. // unlock pointer access
  105. LeaveCriticalSection (&pSSRC->critSect);
  106. #if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
  107. if (RTPLogger)
  108. {
  109. //INTEROP
  110. InteropOutput (RTPLogger,
  111. (BYTE FAR*)(pBufs->buf),
  112. (int)pBufs->len,
  113. RTPLOG_SENT_PDU | RTP_PDU);
  114. }
  115. #endif
  116. dwStatus = RRCMws.sendTo (RTPsocket,
  117. pBufs,
  118. dwBufCount,
  119. pNumBytesSent,
  120. socketFlags,
  121. (PSOCKADDR)pTo,
  122. toLen,
  123. pOverlapped,
  124. pCompletionRoutine);
  125. if (dwStatus != SOCKET_ERROR || GetLastError() == WSA_IO_PENDING)
  126. {
  127. DWORD i, cbTransferred = 0;
  128. // assume the send will succeed
  129. /* lock out access to this RTCP session variable */
  130. EnterCriticalSection (&pSSRC->critSect);
  131. // calculate statistics (-DWORD) for the CRSC entry defined
  132. // in the RTP header (but we should remove it from the data structure)
  133. for (i = 0;i < dwBufCount; i++)
  134. cbTransferred += pBufs[i].len;
  135. pSSRC->xmtInfo.dwNumBytesSent += (cbTransferred -
  136. (sizeof(RTP_HDR_T) - sizeof(DWORD)));
  137. pSSRC->xmtInfo.dwNumPcktSent++;
  138. /* unlock access */
  139. LeaveCriticalSection (&pSSRC->critSect);
  140. }
  141. IN_OUT_STR ("RTP : Exit RTPSendTo()\n");
  142. return (dwStatus);
  143. }
  144. // [EOF]