1 /* Imported from the dvbstream-0.2 project */
10 #include <netinet/in.h>
11 #include <sys/socket.h>
12 #include <arpa/inet.h>
18 /* MPEG-2 TS RTP stack */
23 void initrtp(struct rtpheader
*foo
) { /* fill in the MPEG-2 TS deefaults */
24 /* Note: MPEG-2 TS defines a timestamping base frequency of 90000 Hz. */
30 foo
->b
.pt
=33; /* MPEG-2 TS */
31 foo
->b
.sequence
=rand() & 65535;
32 foo
->timestamp
=rand();
36 /* Send a single RTP packet, converting the RTP header to network byte order. */
37 int sendrtp(int fd
, struct sockaddr_in
*sSockAddr
, struct rtpheader
*foo
, char *data
, int len
) {
38 char *buf
=(char*)alloca(len
+sizeof(struct rtpheader
));
40 int *outcast
=(int *)buf
;
41 outcast
[0]=htonl(cast
[0]);
42 outcast
[1]=htonl(cast
[1]);
43 memmove(outcast
+2,data
,len
);
44 fprintf(stderr
,"v=%x %x\n",foo
->b
.v
,buf
[0]);
45 return sendto(fd
,buf
,len
+3,0,(struct sockaddr
*)sSockAddr
,sizeof(*sSockAddr
));
48 int getrtp2(int fd
, struct rtpheader
*rh
, char** data
, int* lengthData
) {
49 static char buf
[1600];
51 char* charP
= (char*) &intP
;
54 lengthPacket
=recv(fd
,buf
,1590,0);
58 fprintf(stderr
,"socket read error\n");
61 if (lengthPacket
<12) {
62 fprintf(stderr
,"packet too small (%d) to be an rtp frame (>12bytes)\n", lengthPacket
);
65 rh
->b
.v
= (unsigned int) ((buf
[0]>>6)&0x03);
66 rh
->b
.p
= (unsigned int) ((buf
[0]>>5)&0x01);
67 rh
->b
.x
= (unsigned int) ((buf
[0]>>4)&0x01);
68 rh
->b
.cc
= (unsigned int) ((buf
[0]>>0)&0x0f);
69 rh
->b
.m
= (unsigned int) ((buf
[1]>>7)&0x01);
70 rh
->b
.pt
= (unsigned int) ((buf
[1]>>0)&0x7f);
72 memcpy(charP
+2,&buf
[2],2);
73 rh
->b
.sequence
= ntohl(intP
);
75 memcpy(charP
,&buf
[4],4);
76 rh
->timestamp
= ntohl(intP
);
78 headerSize
= 12 + 4*rh
->b
.cc
; /* in bytes */
80 *lengthData
= lengthPacket
- headerSize
;
81 *data
= (char*) buf
+ headerSize
;
83 // fprintf(stderr,"Reading rtp: v=%x p=%x x=%x cc=%x m=%x pt=%x seq=%x ts=%x lgth=%d\n",rh->b.v,rh->b.p,rh->b.x,rh->b.cc,rh->b.m,rh->b.pt,rh->b.sequence,rh->timestamp,lengthPacket);
88 /* Send a single RTP packet, converting the RTP header to network byte order. */
89 int sendrtp2(int fd
, struct sockaddr_in
*sSockAddr
, struct rtpheader
*foo
, char *data
, int len
) {
90 char *buf
=(char*)alloca(len
+72);
92 char* charP
= (char*) &intP
;
95 buf
[0] |= ((((char) foo
->b
.v
)<<6)&0xc0);
96 buf
[0] |= ((((char) foo
->b
.p
)<<5)&0x20);
97 buf
[0] |= ((((char) foo
->b
.x
)<<4)&0x10);
98 buf
[0] |= ((((char) foo
->b
.cc
)<<0)&0x0f);
100 buf
[1] |= ((((char) foo
->b
.m
)<<7)&0x80);
101 buf
[1] |= ((((char) foo
->b
.pt
)<<0)&0x7f);
102 intP
= htonl(foo
->b
.sequence
);
103 memcpy(&buf
[2],charP
+2,2);
104 intP
= htonl(foo
->timestamp
);
105 memcpy(&buf
[4],&intP
,4);
106 /* SSRC: not implemented */
111 headerSize
= 12 + 4*foo
->b
.cc
; /* in bytes */
112 memcpy(buf
+headerSize
,data
,len
);
114 // fprintf(stderr,"Sending rtp: v=%x p=%x x=%x cc=%x m=%x pt=%x seq=%x ts=%x lgth=%d\n",foo->b.v,foo->b.p,foo->b.x,foo->b.cc,foo->b.m,foo->b.pt,foo->b.sequence,foo->timestamp,len+headerSize);
117 return sendto(fd
,buf
,len
+headerSize
,0,(struct sockaddr
*)sSockAddr
,sizeof(*sSockAddr
));
121 int getrtp(int fd
, struct rtpheader
*rh
, char** data
, int* lengthData
) {
122 static char buf
[1600];
126 lengthPacket
=recv(fd
,buf
,1590,0);
127 // FIXME: error handling to write here
129 *lengthData
= lengthPacket
- headerSize
;
130 *data
= (char*) buf
+ headerSize
;
131 fprintf(stderr
,"[%d] %02x %x\n",lengthPacket
,buf
[8],buf
[0]);
135 /* create a sender socket. */
136 int makesocket(char *szAddr
,unsigned short port
,int TTL
,struct sockaddr_in
*sSockAddr
) {
138 struct sockaddr_in sin
;
139 char cTtl
= (char)TTL
;
142 int iSocket
= socket( AF_INET
, SOCK_DGRAM
, 0 );
145 fprintf(stderr
,"socket() failed.\n");
149 sSockAddr
->sin_family
= sin
.sin_family
= AF_INET
;
150 sSockAddr
->sin_port
= sin
.sin_port
= htons(port
);
151 sSockAddr
->sin_addr
.s_addr
= inet_addr(szAddr
);
153 iRet
= setsockopt(iSocket
, SOL_SOCKET
, SO_REUSEADDR
, &iLoop
, sizeof(int));
155 fprintf(stderr
,"setsockopt SO_REUSEADDR failed\n");
159 iRet
= setsockopt(iSocket
, IPPROTO_IP
, IP_MULTICAST_TTL
, &cTtl
, sizeof(char));
161 fprintf(stderr
,"setsockopt IP_MULTICAST_TTL failed. multicast in kernel?\n");
166 iRet
= setsockopt(iSocket
, IPPROTO_IP
, IP_MULTICAST_LOOP
,
167 &cLoop
, sizeof(char));
169 fprintf(stderr
,"setsockopt IP_MULTICAST_LOOP failed. multicast in kernel?\n");
176 /* create a receiver socket, i.e. join the multicast group. */
177 int makeclientsocket(char *szAddr
,unsigned short port
,int TTL
,struct sockaddr_in
*sSockAddr
) {
178 int socket
=makesocket(szAddr
,port
,TTL
,sSockAddr
);
180 struct sockaddr_in sin
;
181 unsigned int tempaddr
;
182 sin
.sin_family
=AF_INET
;
183 sin
.sin_port
=htons(port
);
184 sin
.sin_addr
.s_addr
=inet_addr(szAddr
);
185 if (bind(socket
,(struct sockaddr
*) &sin
,sizeof(sin
))) {
186 perror("bind failed");
189 tempaddr
=inet_addr(szAddr
);
190 if ((ntohl(tempaddr
) >> 28) == 0xe) {
191 blub
.imr_multiaddr
.s_addr
= inet_addr(szAddr
);
192 blub
.imr_interface
.s_addr
= 0;
193 if (setsockopt(socket
,IPPROTO_IP
,IP_ADD_MEMBERSHIP
,&blub
,sizeof(blub
))) {
194 perror("setsockopt IP_ADD_MEMBERSHIP failed (multicast kernel?)");