blob: c451d3ee870b010c89870e20a930ab3da3819e89 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2001-2005 Federico Montesino Pouzols <fedemp@altern.org>
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16//
17// As a special exception, you may use this file as part of a free software
18// library without restriction. Specifically, if other files instantiate
19// templates or use macros or inline functions from this file, or you compile
20// this file and link it with other files to produce an executable, this
21// file does not by itself cause the resulting executable to be covered by
22// the GNU General Public License. This exception does not however
23// invalidate any other reasons why the executable file might be covered by
24// the GNU General Public License.
25//
26// This exception applies only to the code released under the name GNU
27// ccRTP. If you copy code from other releases into a copy of GNU
28// ccRTP, as the General Public License permits, the exception does
29// not apply to the code that you add in this way. To avoid misleading
30// anyone as to the status of such modified files, you must delete
31// this exception notice from them.
32//
33// If you write modifications of your own for GNU ccRTP, it is your choice
34// whether to permit this exception to apply to your modifications.
35// If you do not wish that, delete this exception notice.
36//
37
38#ifndef CCRTP_CHANNEL_H_
39#define CCRTP_CHANNEL_H_
40
41#include <ccrtp/base.h>
42
43#ifndef WIN32
44#include <sys/ioctl.h>
45inline size_t ccioctl(SOCKET so, int request, size_t& len)
46{ return ::ioctl(so,request,&len); }
47#else
48inline size_t ccioctl(SOCKET so, int request, size_t& len )
49{
50 unsigned long l;
51 size_t result = 0;
52 ::ioctlsocket(so,request,&l);
53 len = l;
54 return result;
55}
56#endif
57
58#ifdef CCXX_NAMESPACES
59namespace ost {
60#endif
61
62/**
63 * @file channel.h
64 *
65 * Definition of socket classes for different underlying transport
66 * and/or network protocols that can be used to instantiate the
67 * TRTPSessionBase template.
68 **/
69
70/**
71 * @defgroup sockets Underlying transport protocol socket classes.
72 * @{
73 **/
74
75/**
76 * @class RTPBaseUDPIPv4Socket
77 * @short A UDP/IPv4 socket class targetted at RTP stacks.
78 *
79 * This class provides a flat interface that includes all the services
80 * required by an RTP stack.
81 *
82 * It can be used in two ways:
83 *
84 * To instantiate the DualSocket template, which will be used to
85 * instantiate an RTP stack template (such as TRTPSessionBase).
86 *
87 * To directly instantiate an RTP stack template (such as
88 * TRTPSessionBase).
89 *
90 * This class offers an example of the interface that other classes
91 * should provide in order to specialize the ccRTP stack for different
92 * underlying protocols.
93 *
94 * @author Federico Montesino Pouzols <fedemp@altern.org>
95 **/
96class RTPBaseUDPIPv4Socket : private UDPSocket
97{
98public:
99 /**
100 * Constructor for receiver.
101 **/
102 RTPBaseUDPIPv4Socket(const InetAddress& ia, tpport_t port) :
103 UDPSocket(ia,port)
104 { }
105
106 inline ~RTPBaseUDPIPv4Socket()
107 { endSocket(); }
108
109 inline bool
110 isPendingRecv(microtimeout_t timeout)
111 { return UDPSocket::isPending(UDPSocket::pendingInput, timeout); }
112
113 inline InetHostAddress
114 getSender(tpport_t& port) const
115 { return UDPSocket::getSender(&port); }
116
117 inline size_t
118 recv(unsigned char* buffer, size_t len)
119 { return UDPSocket::receive(buffer, len); }
120
121 /**
122 * Get size of next datagram waiting to be read.
123 **/
124 inline size_t
125 getNextPacketSize() const
126 { size_t len; ccioctl(UDPSocket::so,FIONREAD,len); return len; }
127
128 Socket::Error
129 setMulticast(bool enable)
130 { return UDPSocket::setMulticast(enable); }
131
132 inline Socket::Error
133 join(const InetMcastAddress& ia, uint32 iface)
134 { return UDPSocket::join(ia,iface); }
135
136 inline Socket::Error
137 drop(const InetMcastAddress& ia)
138 { return UDPSocket::drop(ia); }
139
140 inline Socket::Error
141 setTimeToLive(unsigned char ttl)
142 { return UDPSocket::setTimeToLive(ttl); }
143
144 /**
145 * Constructor for transmitter.
146 **/
147 RTPBaseUDPIPv4Socket() :
148 UDPSocket()
149 { }
150
151 inline void
152 setPeer(const InetAddress &ia, tpport_t port)
153 {UDPSocket::setPeer((InetHostAddress&)ia, port);}
154
155 inline size_t
156 send(const unsigned char* const buffer, size_t len)
157 { return UDPSocket::send(buffer, len); }
158
159 inline SOCKET getRecvSocket() const
160 { return UDPSocket::so; }
161
162 // common
163 inline void
164 endSocket()
165 { UDPSocket::endSocket(); }
166};
167
168/**
169 * @class DualUDPIPv4Socket
170 * @short A socket class based on two UDP/IPv4 sockets.
171 *
172 * Defines a communication channel for RTP data and/or RTCP streams.
173 * Sockets used to instantiate this template must define a framing
174 * mechanism (UDP does not need any addition, TCP does).
175 *
176 * This class implements a socket as a pair of UDP/IPv4 sockets,
177 * alllowing both transmission and reception of packets in unicast as
178 * well as multicast mode. The implementation of this class relies on
179 * the Common C++ UDPSocket class but provides the interface needed by
180 * a ccRTP stack.
181 *
182 * Normally, RTP stacks will use two objects of this class, one for
183 * RTP data packets transmission/reception and other for RTCP
184 * (control) transmission/reception.
185 *
186 * @author Federico Montesino Pouzols <fedemp@altern.org>
187 **/
188template<class BaseSocket>
189class DualRTPChannel
190{
191public:
192 DualRTPChannel(const InetAddress& ia, tpport_t port)
193 {
194 recvSocket = new BaseSocket(ia,port);
195 sendSocket = new BaseSocket;
196 }
197
198 inline ~DualRTPChannel()
199 { delete sendSocket; delete recvSocket; }
200
201 inline bool
202 isPendingRecv(microtimeout_t timeout) const
203 { return recvSocket->isPendingRecv(timeout); }
204
205 inline InetHostAddress
206 getSender(tpport_t& port) const
207 { return recvSocket->getSender(port); }
208
209 inline size_t
210 recv(unsigned char* buffer, size_t len)
211 { return recvSocket->recv(buffer, len); }
212
213 inline size_t
214 getNextPacketSize() const
215 { return recvSocket->getNextPacketSize(); }
216
217 inline Socket::Error
218 setMulticast(bool enable)
219 { Socket::Error error = recvSocket->setMulticast(enable);
220 if (error) return error;
221 return sendSocket->setMulticast(enable); }
222
223 inline Socket::Error
224 join(const InetMcastAddress& ia, uint32 iface)
225 { return recvSocket->join(ia,iface); }
226
227 inline Socket::Error
228 drop(const InetMcastAddress& ia)
229 { return recvSocket->drop(ia); }
230
231 inline Socket::Error
232 setTimeToLive(unsigned char ttl)
233 { return sendSocket->setTimeToLive(ttl); }
234
235 inline void
236 setPeer(const InetAddress& host, tpport_t port)
237 { sendSocket->setPeer(host,port); }
238
239 inline size_t
240 send(const unsigned char* const buffer, size_t len)
241 { return sendSocket->send(buffer, len); }
242
243 inline SOCKET getRecvSocket() const
244 { return recvSocket->getRecvSocket(); }
245
246 // common.
247 inline void
248 endSocket()
249 { sendSocket->endSocket(); recvSocket->endSocket(); }
250
251private:
252 BaseSocket* sendSocket;
253 BaseSocket* recvSocket;
254};
255
256#ifdef CCXX_IPV6
257
258/**
259 * @class RTPBaseUDPIPv4Socket
260 * @short A UDP/IPv6 socket class targetted at RTP stacks.
261 *
262 * This class provides a flat interface that includes all the services
263 * required by an RTP stack.
264 *
265 * It can be used in two ways:
266 *
267 * To instantiate the DualSocket template, which will be used to
268 * instantiate an RTP stack template (such as TRTPSessionBaseIPV6).
269 *
270 * To directly instantiate an RTP stack template (such as
271 * TRTPSessionBaseIPV6).
272 *
273 * This class offers an example of the interface that other classes
274 * should provide in order to specialize the ccRTP stack for different
275 * underlying protocols.
276 *
277 * @author David Sugar <dyfet@gnutelephony.org>
278 **/
279class RTPBaseUDPIPv6Socket : private UDPSocket
280{
281public:
282 /**
283 * Constructor for receiver.
284 **/
285 RTPBaseUDPIPv6Socket(const IPV6Address& ia, tpport_t port) :
286 UDPSocket(ia,port)
287 { }
288
289 inline ~RTPBaseUDPIPv6Socket()
290 { endSocket(); }
291
292 inline bool
293 isPendingRecv(microtimeout_t timeout)
294 { return UDPSocket::isPending(UDPSocket::pendingInput, timeout); }
295
296 inline IPV6Host
297 getSender(tpport_t& port) const
298 { return UDPSocket::getIPV6Sender(&port); }
299
300 inline size_t
301 recv(unsigned char* buffer, size_t len)
302 { return UDPSocket::receive(buffer, len); }
303
304 /**
305 * Get size of next datagram waiting to be read.
306 **/
307 inline size_t
308 getNextPacketSize() const
309 { size_t len; ccioctl(UDPSocket::so,FIONREAD,len); return len; }
310
311 Socket::Error
312 setMulticast(bool enable)
313 { return UDPSocket::setMulticast(enable); }
314
315 inline Socket::Error
316 join(const IPV6Multicast& ia, uint32 iface)
317 { return Socket::join(ia); }
318
319 inline Socket::Error
320 drop(const IPV6Multicast& ia)
321 { return UDPSocket::drop(ia); }
322
323 inline Socket::Error
324 setTimeToLive(unsigned char ttl)
325 { return UDPSocket::setTimeToLive(ttl); }
326
327 /**
328 * Constructor for transmitter.
329 **/
330 RTPBaseUDPIPv6Socket() :
331 UDPSocket()
332 { }
333
334 inline void
335 setPeer(const IPV6Host &ia, tpport_t port)
336 {UDPSocket::setPeer(ia, port);}
337
338 inline size_t
339 send(const unsigned char* const buffer, size_t len)
340 { return UDPSocket::send(buffer, len); }
341
342 inline SOCKET getRecvSocket() const
343 { return UDPSocket::so; }
344
345 // common
346 inline void
347 endSocket()
348 { UDPSocket::endSocket(); }
349};
350
351/**
352 * @class DualUDPIPv6Socket
353 * @short A socket class based on two UDP/IPv6 sockets.
354 *
355 * Defines a communication channel for RTP data and/or RTCP streams.
356 * Sockets used to instantiate this template must define a framing
357 * mechanism (UDP does not need any addition, TCP does).
358 *
359 * This class implements a socket as a pair of UDP/IPv6 sockets,
360 * alllowing both transmission and reception of packets in unicast as
361 * well as multicast mode. The implementation of this class relies on
362 * the Common C++ UDPSocket class but provides the interface needed by
363 * a ccRTP stack.
364 *
365 * Normally, RTP stacks will use two objects of this class, one for
366 * RTP data packets transmission/reception and other for RTCP
367 * (control) transmission/reception.
368 *
369 * @author David Sugar <dyfet@gnutelephony.org>
370 **/
371template<class BaseSocket>
372class DualRTPChannelIPV6
373{
374public:
375 DualRTPChannelIPV6(const IPV6Host& ia, tpport_t port)
376 {
377 recvSocket = new BaseSocket(ia,port);
378 sendSocket = new BaseSocket;
379 }
380
381 inline ~DualRTPChannelIPV6()
382 { delete sendSocket; delete recvSocket; }
383
384 inline bool
385 isPendingRecv(microtimeout_t timeout) const
386 { return recvSocket->isPendingRecv(timeout); }
387
388 inline IPV6Host
389 getSender(tpport_t& port) const
390 { return recvSocket->getIPV6Sender(port); }
391
392 inline size_t
393 recv(unsigned char* buffer, size_t len)
394 { return recvSocket->recv(buffer, len); }
395
396 inline size_t
397 getNextPacketSize() const
398 { return recvSocket->getNextPacketSize(); }
399
400 inline Socket::Error
401 setMulticast(bool enable)
402 { Socket::Error error = recvSocket->setMulticast(enable);
403 if (error) return error;
404 return sendSocket->setMulticast(enable); }
405
406 inline Socket::Error
407 join(const IPV6Multicast& ia, uint32 iface)
408 { return recvSocket->join(ia,iface); }
409
410 inline Socket::Error
411 drop(const IPV6Multicast& ia)
412 { return recvSocket->drop(ia); }
413
414 inline Socket::Error
415 setTimeToLive(unsigned char ttl)
416 { return sendSocket->setTimeToLive(ttl); }
417
418 inline void
419 setPeer(const IPV6Host& host, tpport_t port)
420 { sendSocket->setPeer(host,port); }
421
422 inline size_t
423 send(const unsigned char* const buffer, size_t len)
424 { return sendSocket->send(buffer, len); }
425
426 inline SOCKET getRecvSocket() const
427 { return recvSocket->getRecvSocket(); }
428
429 // common.
430 inline void
431 endSocket()
432 { sendSocket->endSocket(); recvSocket->endSocket(); }
433
434private:
435 BaseSocket* sendSocket;
436 BaseSocket* recvSocket;
437};
438
439
440typedef DualRTPChannelIPV6<RTPBaseUDPIPv6Socket> DualRTPUDPIPv6Channel;
441typedef RTPBaseUDPIPv6Socket SingleRTPChannelIPV6;
442typedef SingleRTPChannelIPV6 SymmetricRTPChannelIPV6;
443
444#endif
445
446typedef DualRTPChannel<RTPBaseUDPIPv4Socket> DualRTPUDPIPv4Channel;
447
448/**
449 * May be used in applications where using the same socket for both
450 * sending and receiving is not a limitation.
451 **/
452typedef RTPBaseUDPIPv4Socket SingleRTPChannel;
453
454/**
455 * Actually, RTP with a single channel can be called 'Symmetric RTP'
456 **/
457typedef SingleRTPChannel SymmetricRTPChannel;
458
459/** @}*/ // sockets
460
461#ifdef CCXX_NAMESPACES
462}
463#endif
464
465#endif //CCRTP_CHANNEL_H_
466
467/** EMACS **
468 * Local variables:
469 * mode: c++
470 * c-basic-offset: 8
471 * End:
472 */