source: svn/trunk/newcon3bcm2_21bu/dta/src/nexus/rtp.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 10.4 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile:  $
11 * $brcm_Revision:  $
12 * $brcm_Date: $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log:  $
19 *
20 ***************************************************************************/
21#if defined(NEXUS_LINUXUSER)
22#include <stdlib.h>
23#include <string.h>
24#include <netinet/in.h>
25#include <unistd.h>
26#include <stdlib.h>
27#include <stdio.h>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <arpa/inet.h>
31#elif defined(CONFIG_LWIP)
32#include "lwip/ip4.h"
33#endif
34/* MPEG-2 TS RTP stack */
35
36#include "rtp.h"
37
38#ifdef BRCM_DBG
39        #define RTP_DBGMSG(x) { printf("%s:%d-",__FUNCTION__,__LINE__); printf x ; }
40#else
41        #define RTP_DBGMSG(x) ((void)0)
42#endif
43
44
45#if defined(NEXUS_LINUXUSER)
46        #define RTP_SOCKET(a,b,c) socket(a,b,c)
47        #define RTP_SETSOCKOPT(a,b,c,d,e) setsockopt(a,b,c,d,e)
48        #define RTP_SENDTO(a,b,c,d,e,f) sendto(a,b,c,d,e,f)
49        #define RTP_RECV(a,b,c,d) recv(a,b,c,d)
50#elif defined(CONFIG_LWIP)
51        #define RTP_SOCKET(a,b,c) lwip_socket(a,b,c)
52        #define RTP_SETSOCKOPT(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)
53        #define RTP_SENDTO(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f)
54        #define RTP_RECV(a,b,c,d) lwip_recv(a,b,c,d)
55#else
56        #define RTP_SOCKET(a,b,c) 0
57        #define RTP_SETSOCKOP(a,b,c,d,e) 0
58        #define RTP_SENDTO(a,b,c,d,e,f) 0
59        #define RTP_RECV(a,b,c,d) 0
60#endif
61
62/* Payload types (from RFC 1890):
63
64          PT         encoding      audio/video    clock rate    channels
65                                 name          (A/V)          (Hz)          (audio)
66          _______________________________________________________________
67          0          PCMU          A              8000          1
68          1          1016          A              8000          1
69          2          G721          A              8000          1
70          3          GSM           A              8000          1
71          4          unassigned    A              8000          1
72          5          DVI4          A              8000          1
73          6          DVI4          A              16000         1
74          7          LPC           A              8000          1
75          8          PCMA          A              8000          1
76          9          G722          A              8000          1
77          10         L16           A              44100         2
78          11         L16           A              44100         1
79          12         unassigned    A
80          13         unassigned    A
81          14         MPA           A              90000        (see text)
82          15         G728          A              8000          1
83          16--23     unassigned    A
84          24         unassigned    V
85          25         CelB          V              90000
86          26         JPEG          V              90000
87          27         unassigned    V
88          28         nv            V              90000
89          29         unassigned    V
90          30         unassigned    V
91          31         H261          V              90000
92          32         MPV           V              90000
93          33         MP2T          AV             90000
94          34--71     unassigned    ?
95          72--76     reserved      N/A            N/A           N/A
96          77--95     unassigned    ?
97          96--127    dynamic       ?
98
99*/
100/******************************************************************************
101* INPUTS:       p_rtp - uninitialized RTP structure
102*                       buf_len - length to allocate for buffer in bytes
103*                       payload_type - RTP payload type
104* OUTPUTS:      None.
105* RETURNS:      Non-zero on failure.
106* FUNCTION: Initialize rtp structure and header for payload type.
107******************************************************************************/
108
109int init_rtp(
110                        rtp_t *p_rtp,                    /* uninitialized RTP structure */ 
111                        unsigned int buf_len,   /* buffer length in bytes */
112                        int payload_type                 /* payload type of default RTP header (to use for sending) */
113                        )
114{
115        p_rtp->s_fd = -1;
116        p_rtp->rtph.b.v = 2;
117        p_rtp->rtph.b.p = 0;
118        p_rtp->rtph.b.x = 0;
119        p_rtp->rtph.b.cc = 0;
120        p_rtp->rtph.b.m = 0;
121        p_rtp->rtph.b.pt = payload_type;
122        p_rtp->rtph.b.seq = rand() & 65535;
123        p_rtp->rtph.timestamp = rand();
124        p_rtp->buf_len = buf_len;
125        p_rtp->h_len = 12 + (4 * p_rtp->rtph.b.cc);
126        p_rtp->buf = malloc(p_rtp->h_len);
127
128        if (p_rtp->buf == NULL)
129        {
130                return RTP_MEM_ERR;
131        }
132        p_rtp->data_buf = &p_rtp->buf[p_rtp->h_len];
133
134        return RTP_OK;
135}
136
137/******************************************************************************
138* INPUTS:       p_rtp - initialized RTP structure
139* OUTPUTS:      None.
140* RETURNS:      None.
141* FUNCTION: Release rtp structure resources.
142******************************************************************************/
143
144void free_rtp(
145                         rtp_t *p_rtp                    /* initialized RTP structure */
146                         )
147{
148        if (p_rtp->buf)
149        {
150                free(p_rtp->buf);
151        }
152}
153
154/******************************************************************************
155* INPUTS:       p_rtp - initialized RTP structure
156* OUTPUTS:      len - number of payload bytes.
157* RETURNS:      non-zero on error.
158* FUNCTION: receive RTP packet on client socket.
159******************************************************************************/
160#if 0
161static void DBG_HEXDUMP(unsigned char* ptr, unsigned long len)
162{
163        unsigned long i;
164
165        for (i=0; i<len; i++ )
166        {
167                if( i % 16 == 0 )
168                        printf ("\n%03lx: ", (unsigned long) i);
169                printf ("%02x ", ptr[i]);
170        }
171        printf("\n\n");
172}
173#else
174#define DBG_HEXDUMP(ptr, len)
175#endif
176
177int get_rtp(
178                   rtp_t *p_rtp,                   /* initialized RTP structure */
179                   unsigned int *len       /* number of payload bytes */
180                   )
181{
182        *len = RTP_RECV(p_rtp->s_fd,p_rtp->buf,p_rtp->buf_len,0);
183
184        if (*len <= 12)
185        {
186                RTP_DBGMSG(("recv packet length = %d, errno = %d\n",*len,errno));
187                return RTP_RECV_ERR;
188        }
189
190        memcpy(&p_rtp->rtph,p_rtp->buf,sizeof(rtp_header_t));
191
192        p_rtp->rtph.b.seq = ((p_rtp->rtph.b.seq & 0xFF) << 8) | ((p_rtp->rtph.b.seq >> 8) & 0xFF) ;
193        p_rtp->rtph.timestamp = ((p_rtp->rtph.timestamp & 0xFF) << 24) |
194                                                        ((p_rtp->rtph.timestamp & 0xFF00) << 8) |
195                                                        ((p_rtp->rtph.timestamp & 0xFF0000) >> 8) |
196                                                        ((p_rtp->rtph.timestamp & 0xFF000000) >> 24);
197
198        p_rtp->h_len = 12 ; // Not working + (4 * p_rtp->rtph.b.cc);
199        p_rtp->data_buf = &(p_rtp->buf[p_rtp->h_len]);
200        *len -= p_rtp->h_len;
201        return RTP_OK;
202}
203
204/******************************************************************************
205* INPUTS:       p_rtp - initialized RTP structure
206*                       len - number of bytes in payload
207* OUTPUTS:      None.
208* RETURNS:      non-zero on error.
209* FUNCTION: sent RTP packet on server socket.  Assumes data is loaded at
210*                       data_buf which is offset h_len from the beginning of buf so
211*                       if the cc field is changed make sure h_len is recalculated and
212*                       data_buf is set to the proper offset.
213******************************************************************************/
214
215int send_rtp(
216                        rtp_t *p_rtp,                   /* initialized RTP structure */
217                        unsigned char *buf,
218                        unsigned int len                /* number of bytes in payload */
219                        )
220{
221        rtp_header_t *p_rh = buf;
222        memcpy(p_rh,&p_rtp->rtph,p_rtp->h_len);
223        p_rh->b.seq = ((p_rh->b.seq & 0xFF) << 8) | ((p_rh->b.seq >> 8) & 0xFF) ;
224        p_rh->timestamp = ((p_rh->timestamp & 0xFF) << 24) |
225                                          ((p_rh->timestamp & 0xFF00) << 8) |
226                                          ((p_rh->timestamp & 0xFF0000) >> 8) |
227                                          ((p_rh->timestamp & 0xFF000000) >> 24);
228
229        p_rtp->rtph.b.seq++;
230        return RTP_SENDTO(p_rtp->s_fd, buf, len + p_rtp->h_len,
231                                  0,(struct sockaddr *)&(p_rtp->saddr),sizeof(p_rtp->saddr));
232}
233
234/******************************************************************************
235* INPUTS:       p_rtp - initialized RTP structure
236*                       addr_str - ip address in string format
237*                       port - ip port
238*                       ttl - time to live setting.
239* OUTPUTS:      None.
240* RETURNS:      non-zero on error.
241* FUNCTION: Open a socket and configure for sending RTP packets.
242******************************************************************************/
243
244int makesocket_rtp(
245                                  rtp_t *p_rtp,                   /* initialized RTP structure */
246                                  char *addr_str,                 /* address string */
247                                  unsigned short port,    /* create socket for port */
248                                  int ttl                                 /* TTL */
249                                  )
250{
251        int          val = 1;
252        char         c_val = (char)ttl;
253        p_rtp->s_fd = RTP_SOCKET( AF_INET, SOCK_DGRAM, 0 );
254
255        if (p_rtp->s_fd < 0)
256        {
257                RTP_DBGMSG(("socket create failed errno = %d\n",errno));
258                return RTP_SOCKET_ERR;
259        }
260#if defined(CONFIG_LWIP)
261        p_rtp->saddr.sin_len = sizeof(p_rtp->saddr);
262#endif
263        p_rtp->saddr.sin_family = AF_INET;
264        p_rtp->saddr.sin_port = htons(port);
265        p_rtp->saddr.sin_addr.s_addr = inet_addr(addr_str);
266       
267        if (RTP_SETSOCKOPT(p_rtp->s_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)) < 0)
268        {
269                RTP_DBGMSG(("setsockopt SO_REUSEADDR failed errno = %d\n",errno));
270                return RTP_SOCKET_ERR;
271        }
272#ifdef NEXUS_LINUXUSER
273        if (RTP_SETSOCKOPT(p_rtp->s_fd, IPPROTO_IP, IP_MULTICAST_TTL, &c_val, sizeof(char)) < 0)
274        {
275                RTP_DBGMSG(("setsockopt IP_MULTICAST_TTL failed errno = %d\n",errno));
276                return RTP_SOCKET_ERR;
277        }
278
279        c_val = 1;
280        if (RTP_SETSOCKOPT(p_rtp->s_fd, IPPROTO_IP, IP_MULTICAST_LOOP,  &c_val, sizeof(char)) < 0)
281        {
282                RTP_DBGMSG(("setsockopt IP_MULTICAST_LOOP failed errno = %d\n",errno));
283                return RTP_SOCKET_ERR;
284        }
285#endif
286        return RTP_OK;
287}
288
289/******************************************************************************
290* INPUTS:       p_rtp - initialized RTP structure
291*                       addr_str - ip address in string format
292*                       port - ip port
293*                       ttl - time to live setting.
294* OUTPUTS:      None.
295* RETURNS:      non-zero on error.
296* FUNCTION: Open a socket and configure for sending RTP packets.
297******************************************************************************/
298
299int makeclientsocket_rtp(
300                                                rtp_t *p_rtp,                   /* initialized RTP structure */
301                                                char *addr_str,                 /* address string */
302                                                unsigned short port,    /* create socket for port */
303                                                int ttl                                 /* TTL */
304                                                )
305{
306#ifdef NEXUS_LINUXUSER
307        struct ip_mreq  mreq;
308        struct sockaddr_in sin;
309       
310        if (makesocket_rtp(p_rtp,addr_str,port,ttl) != RTP_OK)
311        {
312                RTP_DBGMSG(("makesocket_rtp failed\n"));
313                return RTP_SOCKET_ERR;
314        }
315
316        sin.sin_family = AF_INET;
317        sin.sin_port = htons(port);
318        sin.sin_addr.s_addr = inet_addr(addr_str);
319
320        if (bind(p_rtp->s_fd,(struct sockaddr *)&sin,sizeof(sin)))
321        {
322                RTP_DBGMSG(("bind failed errno = %d\n",errno));
323                return RTP_SOCKET_ERR;
324        }
325
326        if ((ntohl(sin.sin_addr.s_addr) >> 28) == 0xe)
327        {
328                mreq.imr_multiaddr.s_addr = sin.sin_addr.s_addr;
329                mreq.imr_interface.s_addr = 0;
330                if (setsockopt(p_rtp->s_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)))
331                {
332                        RTP_DBGMSG(("setsockopt IP_ADD_MEMBERSHIP failed errno = %d\n",errno));
333                        return RTP_SOCKET_ERR;
334                }
335        }
336#endif
337        return RTP_OK;
338}
Note: See TracBrowser for help on using the repository browser.