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.

456 lines
12 KiB

  1. /*----------------------------------------------------------------------------
  2. * File: RTCPREPT.C
  3. * Product: RTP/RTCP implementation
  4. * Description: Provides report functions for the RRCM implementation.
  5. *
  6. * INTEL Corporation Proprietary Information
  7. * This listing is supplied under the terms of a license agreement with
  8. * Intel Corporation and may not be copied nor disclosed except in
  9. * accordance 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 PRTCP_CONTEXT pRTCPContext;
  20. extern RRCM_WS RRCMws;
  21. /*----------------------------------------------------------------------------
  22. * Function : RTCPReportRequest
  23. * Description: The application request a report for a particular RTCP
  24. * session, identified by the socket descriptor.
  25. *
  26. * Input : RTCPsd: RTCP socket descriptor
  27. * offset: Offset to start from in the list
  28. * *status: -> to the report status information
  29. * *moreEntries: -> to a flag
  30. * numEntriesInBfr: Number of entries in buffer
  31. * pReportBfr: -> to report buffer
  32. * iFilterFlags Bit flags specifying filter to apply
  33. * pFilterPattern -> to value of filter pattern to use
  34. * dwFltrPtrnLen Filter pattern length
  35. *
  36. * Return: OK: RRCM_NoError
  37. * !0: Error code (see RRCM.H)
  38. ---------------------------------------------------------------------------*/
  39. HRESULT WINAPI RTCPReportRequest (SOCKET RTCPsd,
  40. DWORD offset,
  41. DWORD *status,
  42. DWORD *moreEntries,
  43. DWORD numEntriesInBfr,
  44. PRTCP_REPORT pReportBfr,
  45. DWORD dwFilterFlags,
  46. LPVOID pFilterPattern,
  47. DWORD dwFltrPtrnLen)
  48. {
  49. PLINK_LIST pTmp;
  50. PSSRC_ENTRY pRRCM;
  51. DWORD dwStatus = RRCM_NoError;
  52. DWORD numEntryWritten = 0;
  53. DWORD index;
  54. DWORD dwLost;
  55. DWORD dwTmp;
  56. BOOL matched;
  57. IN_OUT_STR ("RTCP: Enter RTCPReportRequest()\n");
  58. ASSERT (pReportBfr);
  59. ASSERT (numEntriesInBfr);
  60. // look for the RTCP session
  61. pTmp = pRTCPContext->RTCPSession.prev;
  62. if (pTmp == NULL)
  63. {
  64. RRCM_DBG_MSG ("RTCP: ERROR - Invalid RTCP session", 0,
  65. __FILE__, __LINE__, DBG_ERROR);
  66. IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
  67. return (MAKE_RRCM_ERROR(RRCMError_RTCPInvalidSession));
  68. }
  69. pRRCM = (PSSRC_ENTRY)((PRTCP_SESSION)pTmp)->XmtSSRCList.prev;
  70. if (pRRCM == NULL)
  71. {
  72. RRCM_DBG_MSG ("RCTP : ERROR - No RTCP Xmt list", 0,
  73. __FILE__, __LINE__, DBG_ERROR);
  74. IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
  75. return (MAKE_RRCM_ERROR(RRCMError_RTCPNoXmtList));
  76. }
  77. while (pTmp)
  78. {
  79. if (pRRCM->RTCPsd == RTCPsd)
  80. break;
  81. else
  82. {
  83. pTmp = pTmp->next;
  84. if (pTmp)
  85. {
  86. pRRCM = (PSSRC_ENTRY)((PRTCP_SESSION)pTmp)->XmtSSRCList.prev;
  87. }
  88. continue;
  89. }
  90. }
  91. if (pTmp == NULL)
  92. {
  93. RRCM_DBG_MSG ("RTCP: ERROR - Invalid RTCP session", 0,
  94. __FILE__, __LINE__, DBG_ERROR);
  95. IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
  96. return (MAKE_RRCM_ERROR(RRCMError_RTCPInvalidSession));
  97. }
  98. if (dwFilterFlags && (pFilterPattern == NULL))
  99. {
  100. RRCM_DBG_MSG ("RTCP: ERROR - Invalid RTCP FilterPattern is NULL", 0,
  101. __FILE__, __LINE__, DBG_ERROR);
  102. IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
  103. return (MAKE_RRCM_ERROR(RRCMError_RTCPInvalidRequest));
  104. }
  105. // go through the list of transmitters for this RTCP session
  106. pRRCM = (PSSRC_ENTRY)((PRTCP_SESSION)pTmp)->XmtSSRCList.prev;
  107. index = 0;
  108. while (pRRCM && numEntriesInBfr)
  109. {
  110. // go to the desired offset
  111. if (offset)
  112. {
  113. offset--;
  114. pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
  115. continue;
  116. }
  117. if (dwFilterFlags)
  118. {
  119. matched = FALSE;
  120. switch (dwFilterFlags)
  121. {
  122. case FLTR_SSRC:
  123. if(pRRCM->SSRC == *((DWORD *)pFilterPattern))
  124. matched=TRUE;
  125. break;
  126. case FLTR_CNAME:
  127. if((memcmp ((char *)pFilterPattern,
  128. pRRCM->cnameInfo.sdesBfr,
  129. dwFltrPtrnLen)) == 0)
  130. matched = TRUE;
  131. break;
  132. default:
  133. RRCM_DBG_MSG ("RTCP: ERROR - Invalid FilterFlag", 0,
  134. __FILE__, __LINE__, DBG_ERROR);
  135. IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
  136. return (MAKE_RRCM_ERROR(RRCMError_RTCPNotImpl));
  137. }
  138. if (!matched)
  139. {
  140. pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
  141. continue;
  142. }
  143. else
  144. numEntriesInBfr--;
  145. }
  146. else
  147. numEntriesInBfr--;
  148. // fill in the our active Sender report information
  149. pReportBfr[index].status = LOCAL_SSRC_RPT;
  150. pReportBfr[index].ssrc = pRRCM->SSRC;
  151. // lock-out bytes update
  152. EnterCriticalSection (&pRRCM->critSect);
  153. pReportBfr[index].dwSrcNumPcktRealTime = pRRCM->xmtInfo.dwNumPcktSent;
  154. pReportBfr[index].dwSrcNumByteRealTime = pRRCM->xmtInfo.dwNumBytesSent;
  155. // release lock
  156. LeaveCriticalSection (&pRRCM->critSect);
  157. // a source - It's supposed to know it's own payload type
  158. pReportBfr[index].PayLoadType = UNKNOWN_PAYLOAD_TYPE;
  159. // our own sampling frequency
  160. pReportBfr[index].dwStreamClock = pRRCM->dwStreamClock;
  161. if (pRRCM->cnameInfo.dwSdesLength)
  162. {
  163. memcpy (pReportBfr[index].cname,
  164. pRRCM->cnameInfo.sdesBfr,
  165. pRRCM->cnameInfo.dwSdesLength);
  166. pReportBfr[index].dwCnameLen = pRRCM->cnameInfo.dwSdesLength;
  167. }
  168. if (pRRCM->nameInfo.dwSdesLength)
  169. {
  170. memcpy (pReportBfr[index].name,
  171. pRRCM->nameInfo.sdesBfr,
  172. pRRCM->nameInfo.dwSdesLength);
  173. pReportBfr[index].dwNameLen = pRRCM->nameInfo.dwSdesLength;
  174. }
  175. if (pRRCM->fromLen)
  176. {
  177. memcpy (&pReportBfr[index].fromAddr,
  178. &pRRCM->from,
  179. pRRCM->fromLen);
  180. pReportBfr[index].dwFromLen = pRRCM->fromLen;
  181. }
  182. numEntryWritten++;
  183. index++;
  184. // go to next entry
  185. pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
  186. }
  187. // go through the list of receivers for this RTCP session
  188. pRRCM = (PSSRC_ENTRY)((PRTCP_SESSION)pTmp)->RcvSSRCList.prev;
  189. while (pRRCM && numEntriesInBfr)
  190. {
  191. // go to the desired offset
  192. if (offset)
  193. {
  194. offset--;
  195. pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
  196. continue;
  197. }
  198. if (dwFilterFlags)
  199. {
  200. matched = FALSE;
  201. switch (dwFilterFlags)
  202. {
  203. case FLTR_SSRC:
  204. if(pRRCM->SSRC == *((DWORD *)pFilterPattern))
  205. matched=TRUE;
  206. break;
  207. case FLTR_CNAME:
  208. if((memcmp ((char *)pFilterPattern,
  209. pRRCM->cnameInfo.sdesBfr,
  210. dwFltrPtrnLen)) == 0)
  211. matched = TRUE;
  212. break;
  213. default:
  214. RRCM_DBG_MSG ("RTCP: ERROR - Invalid FilterFlag", 0,
  215. __FILE__, __LINE__, DBG_ERROR);
  216. IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
  217. return (MAKE_RRCM_ERROR(RRCMError_RTCPNotImpl));
  218. }
  219. if (!matched)
  220. {
  221. pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
  222. continue;
  223. }
  224. else
  225. numEntriesInBfr--;
  226. }
  227. else
  228. numEntriesInBfr--;
  229. // fill in the Receiver report information
  230. pReportBfr[index].ssrc = pRRCM->SSRC;
  231. pReportBfr[index].status = REMOTE_SSRC_RPT;
  232. // lock-out counters update
  233. EnterCriticalSection (&pRRCM->critSect);
  234. #ifdef ENABLE_FLOATING_POINT
  235. pReportBfr[index].SrcJitter = pRRCM->rcvInfo.interJitter;
  236. #else
  237. // Check RFC for details of the round off
  238. pReportBfr[index].SrcJitter = pRRCM->rcvInfo.interJitter >> 4;
  239. #endif
  240. pReportBfr[index].dwSrcXtndNum =
  241. pRRCM->rcvInfo.XtendedSeqNum.seq_union.dwXtndedHighSeqNumRcvd;
  242. // real time receive information
  243. pReportBfr[index].dwSrcNumPcktRealTime = pRRCM->rcvInfo.dwNumPcktRcvd;
  244. pReportBfr[index].dwSrcNumByteRealTime = pRRCM->rcvInfo.dwNumBytesRcvd;
  245. // get sender information from Sender's RTCP report
  246. pReportBfr[index].dwSrcNumPckt = pRRCM->xmtInfo.dwNumPcktSent;
  247. pReportBfr[index].dwSrcNumByte = pRRCM->xmtInfo.dwNumBytesSent;
  248. pReportBfr[index].dwSrcLsr = pRRCM->xmtInfo.dwLastSR;
  249. pReportBfr[index].dwSrcNtpMsw = pRRCM->xmtInfo.dwNTPmsw;
  250. pReportBfr[index].dwSrcNtpLsw = pRRCM->xmtInfo.dwNTPlsw;
  251. pReportBfr[index].dwSrcRtpTs = pRRCM->xmtInfo.dwRTPts;
  252. dwLost = getSSRCpcktLoss (pRRCM, FALSE);
  253. // release lock
  254. LeaveCriticalSection (&pRRCM->critSect);
  255. // the last payload seen on this RTP stream
  256. pReportBfr[index].PayLoadType = pRRCM->PayLoadType;
  257. // last report received time
  258. pReportBfr[index].dwLastReportRcvdTime = pRRCM->dwLastReportRcvdTime;
  259. // fraction lost is in network byte order
  260. pReportBfr[index].SrcFraction = (dwLost & 0xFF);
  261. // cumulative lost is a 24 bits value in network byte order
  262. RRCMws.ntohl (pRRCM->RTPsd, dwLost, &dwTmp);
  263. dwTmp &= 0x00FFFFFF;
  264. pReportBfr[index].SrcNumLost = dwTmp;
  265. // get feedback information
  266. if (pRRCM->rrFeedback.SSRC)
  267. {
  268. pReportBfr[index].status |= FEEDBACK_FOR_LOCAL_SSRC_PRESENT;
  269. memcpy (&pReportBfr[index].feedback, &pRRCM->rrFeedback,
  270. sizeof(RTCP_FEEDBACK));
  271. }
  272. if (pRRCM->cnameInfo.dwSdesLength)
  273. {
  274. memcpy (pReportBfr[index].cname,
  275. pRRCM->cnameInfo.sdesBfr,
  276. pRRCM->cnameInfo.dwSdesLength);
  277. pReportBfr[index].dwCnameLen = pRRCM->cnameInfo.dwSdesLength;
  278. }
  279. if (pRRCM->nameInfo.dwSdesLength)
  280. {
  281. memcpy (pReportBfr[index].name,
  282. pRRCM->nameInfo.sdesBfr,
  283. pRRCM->nameInfo.dwSdesLength);
  284. pReportBfr[index].dwNameLen = pRRCM->nameInfo.dwSdesLength;
  285. }
  286. if (pRRCM->fromLen)
  287. {
  288. memcpy (&pReportBfr[index].fromAddr,
  289. &pRRCM->from,
  290. pRRCM->fromLen);
  291. pReportBfr[index].dwFromLen = pRRCM->fromLen;
  292. }
  293. numEntryWritten++;
  294. index++;
  295. // go to next entry
  296. pRRCM = (PSSRC_ENTRY)pRRCM->SSRCList.next;
  297. }
  298. // check to see if there are additional entries
  299. if (pRRCM != NULL)
  300. *moreEntries = TRUE;
  301. *status = numEntryWritten;
  302. IN_OUT_STR ("RTCP: Exit RTCPReportRequest()\n");
  303. return (dwStatus);
  304. }
  305. /*----------------------------------------------------------------------------
  306. * Function : getRtcpSessionList
  307. * Description: Get a list of current RTCP session.
  308. *
  309. * Input : pSockBfr: -> to a socket buffer
  310. * pNumEntries: -> to number of allocated entries in buffers.
  311. * pNumUpdated: -> number of entries updated
  312. *
  313. * Return: OK: RRCM_NoError
  314. * !0: Error code (see RRCM.H)
  315. ---------------------------------------------------------------------------*/
  316. HRESULT WINAPI getRtcpSessionList (PDWORD_PTR pSockBfr,
  317. DWORD dwNumEntries,
  318. PDWORD pNumUpdated)
  319. {
  320. DWORD dwStatus = RRCM_NoError;
  321. PRTCP_SESSION pRTCP;
  322. PSSRC_ENTRY pSSRC;
  323. IN_OUT_STR ("RTCP: Enter getRtpSessionList()\n");
  324. // lock out session's access
  325. EnterCriticalSection (&pRTCPContext->critSect);
  326. *pNumUpdated = 0;
  327. // look for the RTCP session
  328. pRTCP = (PRTCP_SESSION)pRTCPContext->RTCPSession.prev;
  329. if (pRTCP == NULL)
  330. {
  331. // Unlock out session's access
  332. LeaveCriticalSection (&pRTCPContext->critSect);
  333. IN_OUT_STR ("RTCP: Exit getRtpSessionList()\n");
  334. return (MAKE_RRCM_ERROR (RRCMError_RTPNoSession));
  335. }
  336. // loop through the session's list
  337. while (pRTCP)
  338. {
  339. pSSRC = (PSSRC_ENTRY)pRTCP->XmtSSRCList.prev;
  340. if (pSSRC == NULL)
  341. {
  342. // Unlock out session's access
  343. LeaveCriticalSection (&pRTCPContext->critSect);
  344. RRCM_DBG_MSG ("RCTP : ERROR - No RTCP Xmt list", 0,
  345. __FILE__, __LINE__, DBG_ERROR);
  346. IN_OUT_STR ("RTCP: Exit getRtpSessionList()\n");
  347. return (MAKE_RRCM_ERROR (RRCMError_RTCPNoXmtList));
  348. }
  349. if (dwNumEntries)
  350. {
  351. pSockBfr[*pNumUpdated] = pSSRC->RTCPsd;
  352. *pNumUpdated += 1;
  353. dwNumEntries --;
  354. }
  355. if (dwNumEntries == 0)
  356. {
  357. break;
  358. }
  359. // next entry
  360. pRTCP = (PRTCP_SESSION)(pRTCP->RTCPList.next);
  361. }
  362. // Unlock out session's access
  363. LeaveCriticalSection (&pRTCPContext->critSect);
  364. IN_OUT_STR ("RTCP: Exit getRtpSessionList()\n");
  365. return dwStatus;
  366. }
  367. // [EOF]
  368.