rtp.c
上传用户:biaoge6808
上传日期:2007-08-15
资源大小:42k
文件大小:36k
源码类别:

多媒体

开发平台:

C/C++

  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif
  4. /*
  5. NOTICE:
  6. This document contains information that is proprietary to RADVISION LTD.
  7. No part of this publication may be reproduced in any form whatsoever without
  8. written prior approval by RADVISION LTD.
  9. RADVISION LTD. reserves the right to revise this publication and make changes
  10. without obligation to notify any person of such revisions or changes.
  11. */
  12. /****************************************************************************
  13.   rtp.c  --  RTP implementation.
  14.   Abstract:       The main RTP module file.
  15.   Platforms:      All.
  16. ****************************************************************************/
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <rvcommon.h>
  20. #ifdef _ATM_
  21. #include <rvatm.h>
  22. #endif
  23. #include "bitfield.h"
  24. #include <li.h>
  25. #include <ti.h>
  26. #ifdef _ATM_
  27. #include <liatm.h>
  28. #endif
  29. #include "rtp.h"
  30. #include "rtcp.h"
  31. #ifdef _ATM_
  32. #include "rtpatm.h"
  33. #endif
  34. #define BUILD_VER_NUM(max, min, dot1, dot2) 
  35.     ((UINT32)((max << 24) + (min << 16) + (dot1 << 8) + dot2))
  36. #define VERSION_STR    "4.0.0.24"
  37. #define VERSION_NUM    BUILD_VER_NUM(4, 0, 0, 24)
  38. #define MAXIPS 20
  39. static UINT32 ipBindTo=LI_ADDR_ANY;
  40. static UINT32 myIPs[MAXIPS];
  41. static UINT32 rtpInitialized = 0;
  42. #ifdef _MTS_
  43. static unsigned int seed;
  44. #endif
  45. /* local functions */
  46. static BOOL isMyIP(UINT32 ip);
  47. static void rtpEvent(int socket, liEvents event, int error, void *context);
  48.                        /* == Basic RTP Functions == */
  49. RVAPI
  50. INT32 RVCALLCONV rtpInit(void)
  51. {
  52.     int i;
  53.     UINT32 **ips;
  54.     liInit();
  55.     liThreadAttach(NULL);
  56.     if (rtpInitialized == 0)
  57.     {
  58.         ips = liGetHostAddrs();
  59.         if (!ips)
  60.             return RVERROR;
  61.         for (i=0; ips[i]; i++)
  62.             myIPs[i] = *(ips[i]);
  63. #ifdef _MTS_
  64.         seed = (unsigned)timerGetTimeInSeconds() * myIPs[0];
  65. #else
  66.         srand((unsigned)timerGetTimeInSeconds() * myIPs[0]);
  67. #endif
  68.     }
  69.     rtpInitialized++;
  70.     return 0;
  71. }
  72. RVAPI
  73. INT32 RVCALLCONV rtpInitEx(UINT32 ip)
  74. {
  75.     INT32 rc;
  76.     if ((rc=rtpInit()) != RVERROR)
  77.       ipBindTo=ip;
  78.     return rc;
  79. }
  80. /************************************************************************************
  81.  * rtpSetLocalAddress
  82.  * description: Set the local address to use for calls to rtpOpenXXX functions.
  83.  *              This parameter overrides the value given in rtpInitEx() for all
  84.  *              subsequent calls.
  85.  * input: ip    - Local IP address to use
  86.  * output: none.
  87.  * return value: Non-negative value on success
  88.  *               Negative value on failure
  89.  ***********************************************************************************/
  90. RVAPI
  91. int RVCALLCONV rtpSetLocalAddress(IN UINT32 ip)
  92. {
  93.     ipBindTo = ip;
  94.     return 0;
  95. }
  96. RVAPI
  97. void RVCALLCONV rtpEnd(void)
  98. {
  99.     liThreadDetach(NULL);
  100.     liEnd();
  101.     rtpInitialized--;
  102. }
  103. RVAPI
  104. int RVCALLCONV rtpGetAllocationSize(void)
  105. {
  106.     return sizeof(rtpSession);
  107. }
  108. /************************************************************************************
  109.  * rtpOpenFrom
  110.  * description: Opens an RTP session in the memory that the application allocated.
  111.  * input: port        - The UDP port number to be used for the RTP session.
  112.  *        ssrcPattern - Synchronization source Pattern value for the RTP session.
  113.  *        ssrcMask    - Synchronization source Mask value for the RTP session.
  114.  *        buffer      - Application allocated buffer with a value no less than the
  115.  *                      value returned by the function rtpGetAllocationSize().
  116.  *        bufferSize  - size of the buffer.
  117.  * output: none.
  118.  * return value: If no error occurs, the function returns the handle for the opened RTP
  119.  *               session. Otherwise, it returns NULL.
  120.  ***********************************************************************************/
  121. RVAPI
  122. HRTPSESSION RVCALLCONV rtpOpenFrom(
  123.         IN  UINT16  port,
  124.         IN  UINT32  ssrcPattern,
  125.         IN  UINT32  ssrcMask,
  126.         IN  void*   buffer,
  127.         IN  int     bufferSize)
  128. {
  129.     rtpSession *s = (rtpSession *)buffer;
  130.     if (bufferSize < rtpGetAllocationSize())
  131.         return NULL;
  132.     memset(buffer, 0 , rtpGetAllocationSize());
  133.     s->isAllocated    = FALSE;
  134.     s->sSrcPattern    = ssrcPattern;
  135.     s->sSrcMask       = ssrcMask;
  136.     s->sequenceNumber = (UINT16)
  137. #ifdef _MTS_
  138.       rand_r(&seed);
  139. #else
  140.       rand();
  141. #endif
  142.     s->socket         = liOpen(ipBindTo, port, LI_UDP);
  143. /* h.e */
  144.     if (s->socket == RVERROR)
  145.     {
  146.       return (HRTPSESSION)NULL;
  147.     }
  148.     else
  149. /* === */
  150.     {
  151.       rtpRegenSSRC((HRTPSESSION)s);
  152.       liBlock(s->socket);
  153.       return (HRTPSESSION)s;
  154.     }
  155. }
  156. /************************************************************************************
  157.  * rtpOpen
  158.  * description: Opens an RTP session. The RTP Stack allocates an object and the
  159.  *              memory needed for the RTP session. It also opens a socket and waits
  160.  *              for packets. rtpOpen() also returns the handle of this session to
  161.  *              the application.
  162.  * input: port        - The UDP port number to be used for the RTP session.
  163.  *        ssrcPattern - Synchronization source Pattern value for the RTP session.
  164.  *        ssrcMask    - Synchronization source Mask value for the RTP session.
  165.  * output: none.
  166.  * return value: If no error occurs, the function returns the handle for the opened RTP
  167.  *               session. Otherwise, it returns NULL.
  168.  ***********************************************************************************/
  169. RVAPI
  170. HRTPSESSION RVCALLCONV rtpOpen(
  171.         IN  UINT16  port,
  172.         IN  UINT32  ssrcPattern,
  173.         IN  UINT32  ssrcMask)
  174. {
  175.     return rtpOpenEx(port, ssrcPattern, ssrcMask, NULL);
  176. }
  177. /************************************************************************************
  178.  * rtpOpenEx
  179.  * description: Opens an RTP session and an associated RTCP session.
  180.  * input: port        - The UDP port number to be used for the RTP session.
  181.  *        ssrcPattern - Synchronization source Pattern value for the RTP session.
  182.  *        ssrcMask    - Synchronization source Mask value for the RTP session.
  183.  *        cname       - The unique name representing the source of the RTP data.
  184.  * output: none.
  185.  * return value: If no error occurs, the function returns the handle for the open
  186.  *               RTP session. Otherwise, the function returns NULL.
  187.  ***********************************************************************************/
  188. RVAPI
  189. HRTPSESSION RVCALLCONV rtpOpenEx(
  190.         IN  UINT16  port,
  191.         IN  UINT32  ssrcPattern,
  192.         IN  UINT32  ssrcMask,
  193.         IN  char *  cname)
  194. {
  195.     /* allocate rtp session.*/
  196.     rtpSession *s = (rtpSession*)calloc(rtpGetAllocationSize(),1);
  197.     if (s==NULL)
  198.         return NULL;
  199.     if ((rtpSession *)rtpOpenFrom(port, ssrcPattern, ssrcMask, (void*)s, rtpGetAllocationSize())==NULL)
  200.     {
  201.         free(s);
  202.         return NULL;
  203.     }
  204.     s->isAllocated=TRUE;
  205.     if (cname)
  206.     {
  207.         /* Open a new rtcp session.The port for an RTCP session is always
  208.            (RTP port + 1).*/
  209.         s->hRTCP = rtcpOpen(s->sSrc, (UINT16)((port)?port+1:port), cname);
  210.     }
  211.     return (HRTPSESSION)s;
  212. }
  213. /************************************************************************************
  214.  * rtpClose
  215.  * description: Close RTP session.
  216.  * input: hRTP - Handle of the RTP session.
  217.  * output: none.
  218.  * return value: If an error occurs, the function returns a negative value.
  219.  *               If no error occurs, the function returns a non-negative value.
  220.  ***********************************************************************************/
  221. RVAPI
  222. UINT32 RVCALLCONV rtpClose(
  223.         IN  HRTPSESSION  hRTP)
  224. {
  225.     rtpSession *s = (rtpSession *)hRTP;
  226.     if (s)
  227.     {
  228.         if (s->hRTCP)
  229.             rtcpClose(s->hRTCP);
  230. #ifndef RV_USE_R0
  231.     /*h.e: I'm not sure we have to call liCallOn here for R0. liClose calls it.*/
  232.     liCallOn(s->socket, (liEvents)0, NULL, NULL);
  233. #endif
  234.     /* Send udp data through specified socket to the local host */
  235.         liUdpSend(s->socket, (UINT8*)"", 1, liConvertIp((char*)"127.0.0.1"),
  236.             liGetSockPort(s->socket));
  237.         /* This function closes the specified IP socket and all the socket's connections.*/
  238.         liClose(s->socket);
  239.         if (s->isAllocated)
  240.             free(s);
  241.     }
  242.     return 0;
  243. }
  244. /************************************************************************************
  245.  * rtpGetSSRC
  246.  * description: Returns the current SSRC (synchronization source value) of the RTP session.
  247.  * input: hRTP - Handle of the RTP session.
  248.  * output: none.
  249.  * return value: If no error occurs, the function returns the current SSRC value.
  250.  *               Otherwise, it returns a negative value.
  251.  ***********************************************************************************/
  252. RVAPI
  253. UINT32 RVCALLCONV rtpGetSSRC(
  254.         IN  HRTPSESSION  hRTP)
  255. {
  256.     rtpSession *s = (rtpSession *)hRTP;
  257.     return s->sSrc;
  258. }
  259. /************************************************************************************
  260.  * rtpSetEventHandler
  261.  * description: Set an Event Handler for the RTP session. The application must set
  262.  *              an Event Handler for each RTP session.
  263.  * input: hRTP          - Handle of the RTP session.
  264.  *        eventHandler  - Pointer to the callback function that is called each time a
  265.  *                        new RTP packet arrives to the RTP session.
  266.  *        context       - The parameter is an application handle that identifies the
  267.  *                        particular RTP session. The application passes the handle to
  268.  *                        the Event Handler.
  269.  * output: none.
  270.  * return value: none.
  271.  ***********************************************************************************/
  272. RVAPI
  273. void RVCALLCONV rtpSetEventHandler(
  274.         IN  HRTPSESSION        hRTP,
  275.         IN  LPRTPEVENTHANDLER  eventHandler,
  276.         IN  void *             context)
  277. {
  278.     rtpSession *s = (rtpSession *)hRTP;
  279.     if (s)
  280.     {
  281.         s->eventHandler = eventHandler;
  282.         s->context      = context;
  283.         liUnblock(s->socket);
  284.         liCallOn(s->socket, liEvRead, (eventHandler) ? rtpEvent : NULL, s);
  285.     }
  286. }
  287. /************************************************************************************
  288.  * rtpSetRemoteAddress
  289.  * description: Defines the address of the remote peer or the address of a multicast
  290.  *              group to which the RTP stream will be sent.
  291.  * input: hRTP  - Handle of the RTP session.
  292.  *        ip    - IP address to which RTP packets should be sent.
  293.  *        port  - UDP port to which RTP packets should be sent.
  294.  * output: none.
  295.  * return value: none.
  296.  ***********************************************************************************/
  297. RVAPI
  298. void RVCALLCONV rtpSetRemoteAddress(
  299.         IN HRTPSESSION  hRTP,   /* RTP Session Opaque Handle */
  300.         IN UINT32       ip,
  301.         IN UINT16       port)
  302. {
  303.     rtpSession *s = (rtpSession *)hRTP;
  304.     if (s)
  305.     {
  306.     s->ip   = ip;
  307.     s->port = port;
  308. }
  309. }
  310. /************************************************************************************
  311.  * rtpPack
  312.  * description: This routine sets the RTP header.
  313.  * input: hRTP  - Handle of the RTP session.
  314.  *        buf   - Pointer to buffer containing the RTP packet with room before first
  315.  *                payload byte for RTP header.
  316.  *        len   - Length in bytes of buf.
  317.  *        p     - A struct of RTP param.
  318.  * output: none.
  319.  * return value:  If no error occurs, the function returns the non-neagtive value.
  320.  *                Otherwise, it returns a negative value.
  321.  ***********************************************************************************/
  322. RVAPI
  323. INT32 RVCALLCONV rtpPack(
  324.         IN  HRTPSESSION  hRTP,
  325.         IN  void *       buf,
  326.         IN  INT32        len,
  327.         IN  rtpParam *   p)
  328. {
  329.     rtpSession *s = (rtpSession *)hRTP;
  330.     UINT32 *header;
  331.     UINT32 seq;
  332.     p->sByte-=12;
  333.     p->len=len - p->sByte;
  334.     if (s->useSequenceNumber)
  335.         s->sequenceNumber=p->sequenceNumber;
  336.     p->sequenceNumber=s->sequenceNumber;
  337.     seq = s->sequenceNumber;
  338.     /* sets the fields inside RTP message.*/
  339.     header=(UINT32*)((char*)buf + p->sByte);
  340.     header[0]=0;
  341.     header[0]=bitfieldSet(header[0],2,30,2);
  342.     header[0]=bitfieldSet(header[0],p->marker,23,1);
  343.     header[0]=bitfieldSet(header[0],p->payload,16,7);
  344.     header[0]=bitfieldSet(header[0],seq++,0,16);
  345.     header[1]=p->timestamp;
  346.     header[2]=s->sSrc;
  347.     /* increment the internal sequence number for this session */
  348.     s->sequenceNumber++;
  349.     /* converts an array of 4-byte integers from host format to network format.*/
  350.     liConvertHeader2l((UINT8*)header,0,3);
  351.     return 0;
  352. }
  353. /************************************************************************************
  354.  * rtpWrite
  355.  * description: This routine sends the RTP packet.
  356.  * input: hRTP  - Handle of the RTP session.
  357.  *        buf   - Pointer to buffer containing the RTP packet with room before first
  358.  *                payload byte for RTP header.
  359.  *        len   - Length in bytes of buf.
  360.  *        p     - A struct of RTP param.
  361.  * output: none.
  362.  * return value:  If no error occurs, the function returns the non-neagtive value.
  363.  *                Otherwise, it returns a negative value.
  364.  ***********************************************************************************/
  365. RVAPI
  366. INT32 RVCALLCONV rtpWrite(
  367.         IN  HRTPSESSION  hRTP,
  368.         IN  void *       buf,
  369.         IN  INT32        len,
  370.         IN  rtpParam *   p)
  371. {
  372.     int retVal;
  373.     rtpSession *s = (rtpSession *)hRTP;
  374.     rtpPack(hRTP, buf, len, p);
  375.     /* send udp data through the specified socket to the remote host.*/
  376.     retVal = liUdpSend(s->socket, (UINT8*)buf+p->sByte, p->len, s->ip, s->port);
  377.     if (s->hRTCP  &&  retVal >= 0)
  378.     {
  379.         /* inform the RTCP session about a packet that was sent in the corresponding RTP session.*/
  380.         rtcpRTPPacketSent(s->hRTCP, p->len, p->timestamp);
  381.     }
  382.     return retVal;
  383. }
  384. RVAPI
  385. INT32 RVCALLCONV rtpUnpack(
  386.         IN  HRTPSESSION  hRTP,
  387.         IN  void *buf,
  388.         IN  INT32 len,
  389.         OUT rtpParam* p)
  390. {
  391.     UINT32 *header=(UINT32*)buf;
  392.     if (len || hRTP);
  393.     if (p->len<12)
  394.         return RVERROR;
  395.     liConvertHeader2h((UINT8*)buf,3,(int)bitfieldGet(header[0],24,4));
  396.     p->timestamp=header[1];
  397.     p->sequenceNumber=(UINT16)bitfieldGet(header[0],0,16);
  398.     p->sSrc=header[2];
  399.     p->marker=bitfieldGet(header[0],23,1);
  400.     p->payload=(unsigned char)bitfieldGet(header[0],16,7);
  401.     p->sByte=12+bitfieldGet(header[0],24,4)*sizeof(UINT32);
  402.     if (bitfieldGet(header[0],28,1))/*Extension Bit Set*/
  403.     {
  404.         int xStart=p->sByte / sizeof(UINT32);
  405.         liConvertHeader2h((UINT8*)buf,xStart,1);
  406.         p->sByte+=bitfieldGet(header[xStart],0,16)*sizeof(UINT32);
  407.         if (p->sByte > p->len)
  408.         {
  409.             /* This packet is probably corrupted */
  410.             p->sByte = 12;
  411.             return RVERROR;
  412.         }
  413.     }
  414.     if (bitfieldGet(header[0],29,1))/*Padding Bit Set*/
  415.     {
  416.         p->len-=((char*)buf)[p->len-1];
  417.     }
  418.     return 0;
  419. }
  420. /************************************************************************************
  421.  * rtpRead
  422.  * description: This routine sets the header of the RTP message.
  423.  * input: hRTP  - Handle of the RTP session.
  424.  *        buf   - Pointer to buffer containing the RTP packet with room before first
  425.  *                payload byte for RTP header.
  426.  *        len   - Length in bytes of buf.
  427.  *
  428.  * output: p    - A struct of RTP param,contain the fields of RTP header.
  429.  * return value: If no error occurs, the function returns the non-neagtive value.
  430.  *                Otherwise, it returns a negative value.
  431.  ***********************************************************************************/
  432. RVAPI
  433. INT32 RVCALLCONV rtpRead(
  434.         IN  HRTPSESSION  hRTP,
  435.         IN  void *buf,
  436.         IN  INT32 len,
  437.         OUT rtpParam* p)
  438. {
  439.     rtpSession *s = (rtpSession *)hRTP;
  440.     UINT32 ip;
  441.     UINT16 port;
  442.     p->len=liUdpRecv(s->socket,(unsigned char*)buf,len,&ip,&port);
  443.     liConvertHeader2h((unsigned char*)buf,0,3);
  444.     if (isMyIP(ip) && s->sSrc==((UINT32*)buf)[2]) return RVERROR;
  445.     if (p->len==RVERROR) return RVERROR;
  446.     return rtpUnpack(hRTP, buf, len, p);
  447. }
  448. /************************************************************************************
  449.  * rtpReadEx
  450.  * description: Receives an RTP packet and updates the corresponding RTCP session.
  451.  * input: hRTP      - Handle of the RTP session.
  452.  *        buf       - Pointer to buffer containing the RTP packet with room before first
  453.  *                    payload byte for RTP header.
  454.  *        len       - Length in bytes of buf.
  455.  *        timestamp -
  456.  *        p         - A struct of RTP param,contain the fields of RTP header.
  457.  * output: none.
  458.  * return value: If no error occurs, the function returns the non-neagtive value.
  459.  *               Otherwise, it returns a negative value.
  460.  ***********************************************************************************/
  461. RVAPI
  462. INT32 RVCALLCONV rtpReadEx(
  463.         IN  HRTPSESSION  hRTP,
  464.         IN  void *       buf,
  465.         IN  INT32        len,
  466.         IN  UINT32       timestamp,
  467.         OUT rtpParam *   p)
  468. {
  469.     rtpSession *s = (rtpSession *)hRTP;
  470.     int retVal;
  471.     retVal = rtpRead(hRTP, buf, len, p);
  472.     if (s->hRTCP  &&  retVal >= 0)
  473.     {
  474.         /* Informs the RTCP session about a packet that was received in the corresponding
  475.            RTP session.*/
  476.         rtcpRTPPacketRecv(s->hRTCP, p->sSrc, timestamp,  p->timestamp, p->sequenceNumber);
  477.     }
  478.     return retVal;
  479. }
  480. /************************************************************************************
  481.  * rtpGetPort
  482.  * description: Returns the current port of the RTP session.
  483.  * input: hRTP - Handle of the RTP session.
  484.  * output: none.
  485.  * return value: If no error occurs, the function returns the current port value.
  486.  *               Otherwise, it returns a negative value.
  487.  ***********************************************************************************/
  488. RVAPI
  489. UINT16 RVCALLCONV rtpGetPort(
  490.         IN HRTPSESSION  hRTP)   /* RTP Session Opaque Handle */
  491. {
  492.     UINT16 sockPort;
  493.     rtpSession *s = (rtpSession *)hRTP;
  494.     sockPort=liGetSockPort(s->socket);
  495.     return sockPort;
  496. }
  497. /************************************************************************************
  498.  * rtpGetVersion
  499.  * description:  Returns the RTP version of the installed RTP Stack.
  500.  * input:  none.
  501.  * output: none.
  502.  * return value: If no error occurs, the function returns the current version value.
  503.  *               Otherwise, it returns a negative value.
  504.  ***********************************************************************************/
  505. RVAPI
  506. char * RVCALLCONV rtpGetVersion(void)
  507. {
  508.     return (char*)VERSION_STR;
  509. }
  510. /************************************************************************************
  511.  * rtpGetVersionNum
  512.  * description:  Returns the RTP version of the installed RTP Stack.
  513.  * input:  none.
  514.  * output: none.
  515.  * return value: If no error occurs, the function returns the current version value.
  516.  *               Otherwise, it returns a negative value.
  517.  ***********************************************************************************/
  518. RVAPI
  519. UINT32 RVCALLCONV rtpGetVersionNum(void)
  520. {
  521.     return VERSION_NUM;
  522. }
  523.                     /* == ENDS: Basic RTP Functions == */
  524.                      /* == Accessory RTP Functions == */
  525. /************************************************************************************
  526.  * rtpGetRTCPSession
  527.  * description:  Returns the RTCP session.
  528.  * input:  hRTP - Handle of RTP session.
  529.  * output: none.
  530.  * return value: hRTCP - Handle of RTCP session.
  531.  ***********************************************************************************/
  532. RVAPI
  533. HRTCPSESSION RVCALLCONV rtpGetRTCPSession(
  534.         IN  HRTPSESSION  hRTP)
  535. {
  536.     rtpSession *s = (rtpSession *)hRTP;
  537.     return (s->hRTCP);
  538. }
  539. /************************************************************************************
  540.  * rtpSetRTCPSession
  541.  * description:  set the RTCP session.
  542.  * input:  hRTP  - Handle of RTP session.
  543.  *         hRTCP - Handle of RTCP session.
  544.  * output: none.
  545.  * return value:return 0.
  546.  ***********************************************************************************/
  547. RVAPI
  548. INT32 RVCALLCONV rtpSetRTCPSession(
  549.         IN  HRTPSESSION   hRTP,
  550.         IN  HRTCPSESSION  hRTCP)
  551. {
  552.     rtpSession *s = (rtpSession *)hRTP;
  553.     s->hRTCP = hRTCP;
  554.     return 0;
  555. }
  556. /************************************************************************************
  557.  * rtpGetHeaderLength
  558.  * description:  return the header of RTP message.
  559.  * input:  none.
  560.  * output: none.
  561.  * return value:The return value is twelve.
  562.  ***********************************************************************************/
  563. RVAPI
  564. INT32 RVCALLCONV rtpGetHeaderLength(void)
  565. {
  566.     return 12;
  567. }
  568. /************************************************************************************
  569.  * rtpRegenSSRC
  570.  * description:  Generates a new synchronization source value for the RTP session.
  571.  *               This function, in conjunction with rtpGetSSRC() may be used to
  572.  *               change the SSRC value when an SSRC collision is detected.
  573.  * input:  hRTP  - Handle of RTP session.
  574.  * output: none.
  575.  * return value: ssrc - If an error occurs, the function returns a negative value.
  576.  *               If no error occurs, the function returns a non-negative value.
  577.  ***********************************************************************************/
  578. RVAPI
  579. UINT32 RVCALLCONV rtpRegenSSRC(
  580.         IN  HRTPSESSION  hRTP)
  581. {
  582.     rtpSession *s = (rtpSession *)hRTP;
  583.     /* those line is to prevent collision.*/
  584.     s->sSrc =
  585. #if defined( _MTS_ ) && ! defined( __LINUX__ )
  586.       rand_r(&seed)
  587. #else
  588.     rand()
  589. #endif
  590.       * timerGetTimeInMilliseconds();
  591.     s->sSrc &= ~s->sSrcMask;
  592.     s->sSrc |= s->sSrcPattern;
  593.     return s->sSrc;
  594. }
  595. /************************************************************************************
  596.  * rtpSetGroupAddress
  597.  * description:  Defines a multicast IP for the RTP session.
  598.  * input:  hRTP  - Handle of RTP session.
  599.  *         ip    - Multicast IP address for the RTP session.
  600.  * output: none.
  601.  * return value: return 0.
  602.  ***********************************************************************************/
  603. RVAPI
  604. INT32 RVCALLCONV rtpSetGroupAddress(
  605.         IN HRTPSESSION hRTP,    /* RTP Session Opaque Handle */
  606.         IN UINT32       ip)
  607. {
  608.     rtpSession *s = (rtpSession *)hRTP;
  609.     /* This function adds the specified address (in network format) to the specified
  610.        Multicast interface for the specified socket.*/
  611.     liJoinMulticastGroup(s->socket,ip,LI_ADDR_ANY);
  612.     return 0;
  613. }
  614. /************************************************************************************
  615.  * rtpResume
  616.  * description:  Causes a blocked rtpRead() or rtpReadEx() function running in
  617.  *               another thread to fail.
  618.  * input:  hRTP  - Handle of RTP session.
  619.  * output: none.
  620.  * return value: If an error occurs, the function returns a negative value.
  621.  *               If no error occurs, the function returns a non-negative value.
  622.  ***********************************************************************************/
  623. RVAPI
  624. INT32 RVCALLCONV rtpResume(
  625.         IN  HRTPSESSION hRTP)
  626. {
  627.     rtpSession *s = (rtpSession *)hRTP;
  628.     UINT16 sockPort;
  629.     sockPort=liGetSockPort(s->socket);
  630.     liUdpSend(s->socket, (UINT8*)"", 1, liConvertIp((char*)"127.0.0.1"),
  631.               sockPort);
  632.     return 0;
  633. }
  634. /************************************************************************************
  635.  * rtpUseSequenceNumber
  636.  * description:  Forces the Stack to accept user input for the sequence number of
  637.  *               the RTP packet. The RTP Stack usually determines the sequence number.
  638.  *               However, the application can force its own sequence number.
  639.  *               Call rtpUseSequenceNumber() at the beginning of the RTP session and
  640.  *               then specify the sequence number in the rtpParam structure of the
  641.  *               rtpWrite() function.
  642.  * input:  hRTP  - Handle of RTP session.
  643.  * output: none.
  644.  * return value: return 0.
  645.  ***********************************************************************************/
  646. RVAPI
  647. INT32 RVCALLCONV rtpUseSequenceNumber(
  648.                 IN HRTPSESSION  hRTP)
  649. {
  650.     rtpSession *s = (rtpSession *)hRTP;
  651.     s->useSequenceNumber = 1;
  652.     return 0;
  653. }
  654. /************************************************************************************
  655.  * rtpSetReceiveBufferSize
  656.  * description:  Changes the RTP session receive buffer size.
  657.  * input:  hRTP  - Handle of RTP session.
  658.  * output: none.
  659.  * return value: return 0.
  660.  ***********************************************************************************/
  661. RVAPI
  662. INT32 RVCALLCONV rtpSetReceiveBufferSize(
  663.                 IN HRTPSESSION  hRTP,
  664.         IN int size)
  665. {
  666.     rtpSession *s = (rtpSession *)hRTP;
  667.     /* This function sets the size of the read/write buffers of a socket*/
  668.     liSetSocketBuffers(s->socket,-1,size);
  669.     return 0;
  670. }
  671. /************************************************************************************
  672.  * rtpSetTransmitBufferSize
  673.  * description:  Changes the RTP session transmit buffer size.
  674.  * input:  hRTP - Handle of RTP session.
  675.  *         size - The new transmit buffer size.
  676.  * output: none.
  677.  * return value: return 0.
  678.  ***********************************************************************************/
  679. RVAPI
  680. INT32 RVCALLCONV rtpSetTransmitBufferSize(
  681.                 IN HRTPSESSION  hRTP,
  682.                 IN int size)
  683. {
  684.     rtpSession *s = (rtpSession *)hRTP;
  685.     /* This function sets the size of the read/write buffers of a socket*/
  686.     liSetSocketBuffers(s->socket,size,-1);
  687.     return 0;
  688. }
  689. /************************************************************************************
  690.  * rtpSetTrasmitBufferSize
  691.  * description:  Changes the RTP session transmit buffer size.
  692.  * input:  hRTP - Handle of RTP session.
  693.  *         size - The new transmit buffer size.
  694.  * output: none.
  695.  * return value: return 0.
  696.  * comment     : obsolete function provided for compatibility with prev. version
  697.  ***********************************************************************************/
  698. RVAPI
  699. INT32 RVCALLCONV rtpSetTrasmitBufferSize(
  700.                 IN HRTPSESSION  hRTP,
  701.                 IN int size)
  702. {
  703.   return rtpSetTransmitBufferSize(hRTP, size);
  704. }
  705. /************************************************************************************
  706.  * rtpGetAvailableBytes
  707.  * description:  Gets the number of bytes available for reading in the RTP session.
  708.  * input:  hRTP - Handle of RTP session.
  709.  * output: none.
  710.  * return value: If an error occurs, the function returns a negative value.
  711.  *               If no error occurs, the function returns a non-negative value.
  712.  ***********************************************************************************/
  713. RVAPI
  714. INT32 RVCALLCONV rtpGetAvailableBytes(
  715.                 IN HRTPSESSION  hRTP)
  716. {
  717.     rtpSession *s = (rtpSession *)hRTP;
  718.     int bytes=RVERROR;
  719.     /* This function returns the number of bytes in the specified socket that are
  720.        available for reading.*/
  721.     liBytesAvailable(s->socket, &bytes);
  722.     return bytes;
  723. }
  724.                   /* == ENDS: Accessory RTP Functions == */
  725.                      /* == Internal RTP Functions == */
  726. static void rtpEvent(int socket, liEvents event, int error, void *context)
  727. {
  728.     rtpSession* s=(rtpSession*)context;
  729.     if(socket || event || error);
  730.     if (s  &&  s->eventHandler)
  731.     {
  732.         s->eventHandler((HRTPSESSION)s,s->context);
  733.     }
  734. }
  735. static BOOL isMyIP(UINT32 ip)
  736. {
  737.     int i;
  738.     for (i=0; myIPs[i]; i++)
  739.     {
  740.         if (ip == myIPs[i])
  741.         {
  742.             return TRUE;
  743.         }
  744.     }
  745.     return FALSE;
  746. }
  747.                   /* == ENDS: Internal RTP Functions == */
  748. #ifdef _ATM_
  749.                         /* == RTP ATM Functions == */
  750. INT32 RVCALLCONV rtpatmInit(BOOL bListen, UINT8 atmSelector, UINT16 port)
  751. {
  752.     int res = rtpInit();
  753.     liatmInit();
  754.     return res;
  755. }
  756. RVAPI
  757. void RVCALLCONV rtpatmEnd(void)
  758. {
  759.     rtpEnd();
  760.     liatmEnd();
  761. }
  762. RVAPI
  763. HRTPSESSION RVCALLCONV rtpatmOpenFrom(
  764.         IN  UINT8               atmSelector,
  765.         IN  UINT16              port,
  766.         IN  RTPATMDIRECTION     Direction,
  767.         IN  UINT32              ssrcPattern,
  768.         IN  UINT32              ssrcMask,
  769.         IN  void*               buffer,
  770.         IN  int                 bufferSize)
  771. {
  772.     rtpSession * s  = (rtpSession *)buffer;
  773.     if (bufferSize < rtpGetAllocationSize())
  774.         return NULL;
  775.     memset(buffer, 0 , rtpGetAllocationSize());
  776.     s->bUseATM        = TRUE;
  777.     s->isAllocated    = FALSE;
  778.     s->sSrcPattern    = ssrcPattern;
  779.     s->sSrcMask       = ssrcMask;
  780.     s->sequenceNumber = (UINT16)
  781. #ifdef _MTS_
  782.       rand_r(&seed);
  783. #else
  784.     rand();
  785. #endif
  786.     s->socket = liatmCreateSocket((Direction==ATMLISTEN),atmSelector,port);
  787.     rtpRegenSSRC((HRTPSESSION)s);
  788.     liBlock(s->socket);
  789.     return (HRTPSESSION)s;
  790. }
  791. RVAPI
  792. HRTPSESSION RVCALLCONV rtpatmOpenEx(
  793.         IN  UINT8               atmSelector,
  794.         IN  UINT16              port,
  795.         IN  RTPATMDIRECTION     Direction,
  796.         IN  UINT32              ssrcPattern,
  797.         IN  UINT32              ssrcMask,
  798.         IN  char *              cname)
  799. {
  800.     rtpSession *s  = calloc(rtpGetAllocationSize(),1);
  801.     if (s==NULL)
  802.         return NULL;
  803.     if (rtpatmOpenFrom(atmSelector, port, Direction, ssrcPattern, ssrcMask, (void*)s, rtpGetAllocationSize())==NULL)
  804.     {
  805.         free(s);
  806.         return NULL;
  807.     }
  808.     s->isAllocated=TRUE;
  809.     if (cname)
  810.         s->hRTCP = rtcpOpen(s->sSrc, ++port, cname);
  811.     return (HRTPSESSION) s;
  812. }
  813. RVAPI
  814. HRTPSESSION RVCALLCONV rtpatmOpen(
  815.         IN  UINT8               atmSelector,
  816.         IN  UINT16              port,
  817.         IN  RTPATMDIRECTION     Direction,
  818.         IN  UINT32              ssrcPattern,
  819.         IN  UINT32              ssrcMask)
  820. {
  821.     return rtpatmOpenEx(atmSelector, port, Direction, ssrcPattern, ssrcMask, NULL);
  822. }
  823. RVAPI
  824. UINT32 RVCALLCONV rtpatmClose(IN  HRTPSESSION  hRTP)
  825. {
  826.     rtpSession * s     = (rtpSession *)hRTP;
  827.     UINT8        bzero = 0;
  828.     if (s->hRTCP)
  829.         rtcpClose(s->hRTCP);
  830.     liatmCallOn       (s->socket, 0, NULL, NULL);
  831.     liatmSendData     (s->socket, &bzero, 1);
  832.     liatmDeleteSocket (s->socket);
  833.     if (s->isAllocated)
  834.         free(s);
  835.     return 0;
  836. }
  837. RVAPI
  838. void RVCALLCONV rtpatmSetEventHandler(
  839.         IN  HRTPSESSION        hRTP,
  840.         IN  LPRTPEVENTHANDLER  eventHandler,
  841.         IN  void *             context)
  842. {
  843.     if (hRTP)
  844.     {
  845.         ATMSOCKET socket = ((rtpSession *)hRTP)->socket;
  846.         ((rtpSession *)hRTP)->eventHandler  = eventHandler;
  847.         ((rtpSession *)hRTP)->context       = context;
  848.         liUnblock   (((rtpSession*)hRTP)->socket);
  849.         liatmCallOn (((rtpSession*)hRTP)->socket, liEvRead, (eventHandler) ? rtpEvent:NULL, (void*)hRTP);
  850.     }
  851. }
  852. RVAPI
  853. void RVCALLCONV rtpSetATMRemoteAddress(
  854.     IN HRTPSESSION  hRTP,   /* RTP Session Opaque Handle */
  855.     IN UINT8    *atmAddr,
  856.     IN UINT32   addrLength,
  857.     IN UINT16   selector)
  858. {
  859.     rtpSession *s = (rtpSession *)hRTP;
  860.     if (atmAddr)
  861.     {
  862.         s->atmAddr     = atmAddr;
  863.         s->addrLength  = addrLength;
  864.     }
  865.     if (selector)
  866.         s->selector = selector;
  867.     else
  868.         s->selector = s->atmAddr[s->addrLength-1];
  869. }
  870. RVAPI
  871. INT32 RVCALLCONV rtpatmConnect(IN HRTPSESSION hRTP)
  872. {
  873.     rtpSession * s = (rtpSession*) hRTP;
  874.     int          res;
  875.     res = liatmConnect(s->socket, s->atmAddr, s->addrLength,TRUE,0,(int*)&s->selector);
  876.     /*if (res != RVERROR)
  877.         liatmCallOn (s->socket, liEvRead, (s->eventHandler) ? rtpEvent:NULL, (void*)hRTP);*/
  878.     return res;
  879. }
  880. RVAPI
  881. INT32 RVCALLCONV rtpatmWrite(
  882.         IN  HRTPSESSION  hRTP,
  883.         IN  void *       buf,
  884.         IN  INT32        len,
  885.         IN  rtpParam *   p)
  886. {
  887.     int     retVal;
  888.     UINT32 *header;
  889.     rtpSession *s = (rtpSession *)hRTP;
  890.     if (s->socket==INVALID_SOCKET)
  891.         return RVERROR;
  892.     header = (UINT32*)((char*)buf+p->sByte-12);
  893.     if (s->useSequenceNumber)
  894.         s->sequenceNumber=p->sequenceNumber;
  895.     p->sequenceNumber=s->sequenceNumber;
  896.     header[0]=0;
  897.     header[0]=bitfieldSet(header[0],2,30,2);
  898.     header[0]=bitfieldSet(header[0],p->marker,23,1);
  899.     header[0]=bitfieldSet(header[0],p->payload,16,7);
  900.     header[0]=bitfieldSet(header[0],s->sequenceNumber++,0,16);
  901.     header[1]=p->timestamp;
  902.     header[2]=s->sSrc;
  903.     p->len=len-p->sByte;
  904.     liConvertHeader2l((UINT8*)header,0,3);
  905.     retVal = liatmSendData(s->socket,(UINT8*)header,len-((char*)header-(char*)buf));
  906.     if (s->hRTCP  &&  retVal >= 0)
  907.     {
  908.         rtcpRTPPacketSent(s->hRTCP, p->len, p->timestamp);
  909.     }
  910.     return retVal;
  911. }
  912. RVAPI
  913. INT32 RVCALLCONV rtpatmWriteFirst(
  914.         IN  HRTPSESSION  hRTP,
  915.         IN  void *       buf,
  916.         IN  INT32        len)
  917. {
  918.     int retVal;
  919.     rtpParam p;
  920.     rtpSession *s;
  921.     UINT32 *header;
  922.     memset (&p,0,sizeof(rtpParam));
  923.     p.timestamp = 0;
  924.     p.marker    = TRUE;
  925.     p.payload   = 0; /*PCMU;
  926.     OUT     UINT32  sSrc;
  927.     OUT     UINT16  sequenceNumber;*/
  928.     p.sByte     = 12;
  929.     /*OUT     int     len;*/
  930.     s = (rtpSession *)hRTP;
  931.     header=(UINT32*)((char*)buf+p.sByte-12);
  932.     if (s->useSequenceNumber)
  933.         s->sequenceNumber=p.sequenceNumber;
  934.     p.sequenceNumber=s->sequenceNumber;
  935.     header[0]=0;
  936.     header[0]=bitfieldSet(header[0],2,30,2);
  937.     header[0]=bitfieldSet(header[0],p.marker,23,1);
  938.     header[0]=bitfieldSet(header[0],p.payload,16,7);
  939.     header[0]=bitfieldSet(header[0],s->sequenceNumber++,0,16);
  940.     header[1]=p.timestamp;
  941.     header[2]=s->sSrc;
  942.     p.len=len-p.sByte;
  943.     liConvertHeader2l((UINT8*)header,0,3);
  944.     if (retVal=liatmSendData(s->socket, (UINT8*)header, len-((char*)header-(char*)buf))<0)
  945.         retVal=0;
  946.     if (s->hRTCP  &&  retVal >= 0)
  947.     {
  948.         rtcpRTPPacketSent(s->hRTCP, p.len, p.timestamp);
  949.     }
  950.     return retVal;
  951. }
  952. RVAPI
  953. INT32 RVCALLCONV rtpatmRead(
  954.         IN  HRTPSESSION  hRTP,
  955.         IN  void        *buf,
  956.         IN  INT32        len,
  957.         OUT rtpParam    *p)
  958. {
  959.     rtpSession * s      = (rtpSession *)hRTP;
  960.     UINT32     * header = buf;
  961.     if (s->socket==INVALID_SOCKET)
  962.         return RVERROR;
  963.     p->len = liatmRecvData(s->socket,(char*)buf,len);
  964.     liConvertHeader2h(buf,0,3);
  965.     /*if (isMyIP(ip) && s->sSrc==((UINT32*)buf)[2]) return RVERROR;*/
  966.     if (p->len==RVERROR || p->len<12)
  967.         return RVERROR;
  968.     liConvertHeader2h(buf,3,bitfieldGet(header[0],24,4));
  969.     p->timestamp        = header[1];
  970.     p->sequenceNumber   = (UINT16)bitfieldGet(header[0],0,16);
  971.     p->sSrc             = header[2];
  972.     p->marker           = bitfieldGet(header[0],23,1);
  973.     p->payload          = (unsigned char)bitfieldGet(header[0],16,7);
  974.     p->sByte            = 12 + bitfieldGet(header[0],24,4) * sizeof(UINT32);
  975.     if (bitfieldGet(header[0],28,1))
  976.     {
  977.         int xStart = p->sByte/sizeof(UINT32);
  978.         liConvertHeader2h(buf,xStart,1);
  979.         liConvertHeader2h(buf,xStart+1,bitfieldGet(header[xStart],0,16));
  980.         p->sByte += bitfieldGet(header[xStart],0,16)*sizeof(UINT32);
  981.     }
  982.     return 0;
  983. }
  984. RVAPI
  985. INT32 RVCALLCONV rtpatmReadEx(
  986.         IN  HRTPSESSION  hRTP,
  987.         IN  void *       buf,
  988.         IN  INT32        len,
  989.         IN  UINT32       timestamp,
  990.         OUT rtpParam *   p)
  991. {
  992.     rtpSession *s = (rtpSession *)hRTP;
  993.     int retVal;
  994.     retVal = rtpatmRead(hRTP, buf, len, p);
  995.     if (s->hRTCP  &&  retVal >= 0)
  996.     {
  997.         rtcpRTPPacketRecv(s->hRTCP, p->sSrc, timestamp,  p->timestamp, p->sequenceNumber);
  998.     }
  999.     return retVal;
  1000. }
  1001. RVAPI
  1002. INT32 rtpatmGetATMAddr(IN HRTPSESSION  hRTP, BYTE Addr[ATM_ADDR_SIZE], UINT32 *NumofDigits)
  1003. {
  1004.     return liatmGetLocalAddr(((rtpSession*)hRTP)->socket,Addr,NumofDigits);
  1005. }
  1006. RVAPI
  1007. BOOL RVCALLCONV rtpatmIsATM(IN HRTPSESSION hRTP)
  1008. {
  1009.     return ((rtpSession*)hRTP)->bUseATM;
  1010. }
  1011.                  /* == ENDS: RTP ATM Functions == */
  1012. #endif
  1013. #ifdef __cplusplus
  1014. }
  1015. #endif