diff -uprN ccrtp/AUTHORS ccrtp_dccp/AUTHORS
--- ccrtp/AUTHORS	2009-09-01 15:35:58.000000000 -0300
+++ ccrtp_dccp/AUTHORS	2009-09-01 15:37:23.000000000 -0300
@@ -5,3 +5,4 @@ See also the files THANKS and ChangeLog.
 David Sugar <dyfet@ostel.com> designed and implemented initial ccRTP.
 Federico Montesino Pouzols <fedemp@altern.org> has helped make it work.
 Werner Dittman added SRTP support based on srtp package.
+Ivo Calado<txithihausen@gmail.com>, Heverton Stuart<hevertonsns@gmail.com> and Leandro Sales<leandroal@gmail.com> added support DCCP transport protocol
diff -uprN ccrtp/demo/README ccrtp_dccp/demo/README
--- ccrtp/demo/README	2009-09-01 15:36:03.000000000 -0300
+++ ccrtp_dccp/demo/README	2009-09-01 15:37:23.000000000 -0300
@@ -5,9 +5,13 @@ and illustrating features of ccRTP:
 	* rpthello: illustrates transmission/reception of RTP packets
 	using the RTPSession class.
 
-	* rtpsend: sends RTP/RTCP packets
+	* rtpsend: sends RTP/RTCP packets, using UDP socket
 
-	* rtplisten: waits for RTP/RTCP incoming packets
+	* rtplisten: waits for RTP/RTCP incoming packets, using UDP socket
+
+	* rtpdccpsend: sends RTP/RTCP packets, using DCCP socket
+
+	* rtpdccplisten: waits for RTP/RTCP incoming packets, using DCCP socket
 
 	* rtpduphello: illustrates transmission/reception of RTP packets
 	using RTPDuplex
diff -uprN ccrtp/demo/rtpdccplisten.cpp ccrtp_dccp/demo/rtpdccplisten.cpp
--- ccrtp/demo/rtpdccplisten.cpp	1969-12-31 21:00:00.000000000 -0300
+++ ccrtp_dccp/demo/rtpdccplisten.cpp	2009-09-01 15:37:23.000000000 -0300
@@ -0,0 +1,167 @@
+// rtpdccplisten
+// Listen for RTP packets through of DCCP Socket. This example is based 
+// on demo/rtplisten.cpp program
+// Copyright (C) 2009 Ivo Calado <txithihausen@gmail.com>
+// Copyright (C) 2009 Heverton Stuart <hevertonsns@gmail.com>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#include <cstdlib>
+#include <ccrtp/rtp.h>
+
+#ifdef  CCXX_NAMESPACES
+using namespace ost;
+using namespace std;
+#endif
+
+class Listener: RTPDCCPSession {
+public:
+	Listener(InetMcastAddress& ima, tpport_t port):
+		RTPDCCPSession(ima,port)
+	{ }
+
+	Listener(InetHostAddress& ia, tpport_t port):
+		RTPDCCPSession(ia,port)
+	{ }
+
+	void listen()
+	{
+		cout << "My SSRC identifier is: " 
+		     << hex << (int)getLocalSSRC() << endl;
+
+		defaultApplication().setSDESItem(SDESItemTypeTOOL,
+                                                 "rtpdccplisten demo app.");
+		setExpireTimeout(1000000);
+
+		setPayloadFormat(StaticPayloadFormat(sptPCMU));
+		startRunning();
+		for (;;) {
+			const AppDataUnit* adu;
+			while ( (adu = getData(getFirstTimestamp())) ) {
+				cerr << "I got an app. data unit - "
+				     << adu->getSize()
+				     << " payload octets ("
+				     << "pt " << (int)adu->getType()
+				     << ") from "
+				     << hex << (int)adu->getSource().getID() 
+				     << "@" << dec <<
+					adu->getSource().getNetworkAddress()
+				     << ":" 
+				     << adu->getSource().getDataTransportPort()
+				     << endl;
+				delete adu;
+			}
+			Thread::sleep(7);
+		}
+	}
+
+	// redefined from IncomingDataQueue
+	void onNewSyncSource(const SyncSource& src)
+	{
+		cout << "* New synchronization source: " <<
+		     hex << (int)src.getID() << endl;
+	}
+
+	// redefined from QueueRTCPManager
+	void
+	onGotSR(SyncSource& source, SendReport& SR, uint8 blocks)
+	{
+		RTPDCCPSession::onGotSR(source,SR,blocks);
+		cout << "I got an SR RTCP report from "
+		     << hex << (int)source.getID() << "@"
+		     << dec
+		     << source.getNetworkAddress() << ":" 
+		     << source.getControlTransportPort() << endl;
+	}
+
+	// redefined from QueueRTCPManager
+	void
+	onGotRR(SyncSource& source, RecvReport& RR, uint8 blocks)
+	{
+		RTPDCCPSession::onGotRR(source,RR,blocks);
+		cout << "I got an RR RTCP report from "
+		     << hex << (int)source.getID() << "@"
+		     << dec
+		     << source.getNetworkAddress() << ":" 
+		     << source.getControlTransportPort() << endl;
+	}
+
+	// redefined from QueueRTCPManager
+	bool
+	onGotSDESChunk(SyncSource& source, SDESChunk& chunk, size_t len)
+	{ 
+		bool result = RTPDCCPSession::onGotSDESChunk(source,chunk,len);
+		cout << "I got a SDES chunk from "
+		     << hex << (int)source.getID() << "@" 
+		     << dec
+		     << source.getNetworkAddress() << ":" 
+		     << source.getControlTransportPort()
+		     << " (" 
+		     << source.getParticipant()->getSDESItem(SDESItemTypeCNAME)
+		     << ") " << endl;
+		return result;
+	}
+	
+	void
+	onGotGoodbye(const SyncSource& source, const std::string& reason)
+	{ 
+		cout << "I got a Goodbye packet from "
+		     << hex << (int)source.getID() << "@" 
+		     << dec
+		     << source.getNetworkAddress() << ":" 
+		     << source.getControlTransportPort() << endl;
+		cout << "   Goodbye reason: \"" << reason << "\"" << endl;
+	}
+};
+
+int
+main(int argc, char *argv[])
+{
+        cout << "rtpdccplisten" << endl;
+
+	if (argc != 3) { 
+		cerr << "Syntax: " << " ip port" << endl;
+		exit(1);
+	}
+
+	InetMcastAddress ima;
+	try {
+		ima = InetMcastAddress(argv[1]);
+	} catch (...) {	}
+
+	Listener *foo;
+	tpport_t port = atoi(argv[2]);
+	if ( ima.isInetAddress() ) {
+		foo = new Listener(ima,port);
+		cout << "Listening on multicast address " << ima << ":" << 
+			port << endl;
+	} else {
+		InetHostAddress ia(argv[1]);
+		foo = new Listener(ia,atoi(argv[2]));
+		cout << "Listening on unicast address " << ia << ":" <<
+			port << endl;
+	}
+	cout << "Press Ctrl-C to finish." << endl;
+	foo->listen();
+	delete foo;
+	return 0;
+}
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-basic-offset: 8
+ * End:
+ */
diff -uprN ccrtp/demo/rtpdccpsend.cpp ccrtp_dccp/demo/rtpdccpsend.cpp
--- ccrtp/demo/rtpdccpsend.cpp	1969-12-31 21:00:00.000000000 -0300
+++ ccrtp_dccp/demo/rtpdccpsend.cpp	2009-09-01 15:37:23.000000000 -0300
@@ -0,0 +1,98 @@
+// rtpdccpsend
+// Send for RTP packets through of DCCP Socket. This example is based 
+// on demo/rtpsend.cpp program
+// Copyright (C) 2009 Ivo Calado <txithihausen@gmail.com>
+// Copyright (C) 2009 Heverton Stuart <hevertonsns@gmail.com>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#include <cstdlib>
+#include <ccrtp/rtp.h>
+
+#ifdef  CCXX_NAMESPACES
+using namespace ost;
+using namespace std;
+#endif
+
+/**
+ * @brief This class sends an RTP Packet
+ **/
+class Sender: public RTPDCCPSession, public TimerPort {
+public:
+	Sender(const unsigned char* data, const InetHostAddress& ia, 
+	       tpport_t port, uint32 tstamp, uint16 count, tpport_t port2):
+		RTPDCCPSession(InetHostAddress("0.0.0.0"),port2),
+		packetsPerSecond(10)
+	{
+		uint32 timestamp = tstamp? tstamp : 0;
+		
+		cout << "My SSRC identifier is: " 
+		     << hex << (int)getLocalSSRC() << endl;
+
+		defaultApplication().setSDESItem(SDESItemTypeTOOL,
+                                                 "rtpdccpsend demo app.");
+		setSchedulingTimeout(10000);
+		setExpireTimeout(1000000);
+		
+		if ( !addDestination(ia,port) ) {
+			cerr << "Could not connect" << endl;
+			exit();
+		}
+		
+		setPayloadFormat(StaticPayloadFormat(sptPCMU));
+		startRunning();
+
+		uint16 tstampInc = getCurrentRTPClockRate()/packetsPerSecond;
+		uint32 period = 1000/packetsPerSecond;
+		TimerPort::setTimer(period);
+		for ( int i = 0; i < count ; i++ ) {
+			putData(timestamp + i*tstampInc,
+				data,strlen((char *)data) + 1);
+			Thread::sleep(TimerPort::getTimer());
+			TimerPort::incTimer(period);
+		}
+	}
+
+private:
+	const uint16 packetsPerSecond;
+};
+
+int
+main(int argc, char *argv[])
+{
+        cout << "rtpdccpsend..." << endl;
+
+	if (argc != 7) { 
+                cerr << "Syntax: " << "data host port timestamp count localport" << endl;
+		exit(1);
+	}
+
+	Sender sender((unsigned char *)argv[1], InetHostAddress(argv[2]),
+		      atoi(argv[3]), atoi(argv[4]), atoi(argv[5]), atoi(argv[6]));
+	
+	cout << "I have sent " << argv[5] 
+	     << " RTP packets containing \"" << argv[1]
+	     << "\", with timestamp " << argv[4]
+	     << " to " << argv[2] << ":" << argv[3]
+	     << endl;
+	return 0;
+}
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-basic-offset: 8
+ * End:
+ */
diff -uprN ccrtp/src/ccrtp/channel.h ccrtp_dccp/src/ccrtp/channel.h
--- ccrtp/src/ccrtp/channel.h	2009-09-01 15:36:08.000000000 -0300
+++ ccrtp_dccp/src/ccrtp/channel.h	2009-09-01 15:38:44.000000000 -0300
@@ -39,6 +39,8 @@
 #define CCRTP_CHANNEL_H_
 
 #include <ccrtp/base.h>
+#include <map>
+using namespace std;
 
 #ifndef WIN32
 #include <sys/ioctl.h>
@@ -166,24 +168,146 @@ public:
 };
 
 /**
- * @class DualUDPIPv4Socket
- * @short A socket class based on two UDP/IPv4 sockets.
+ * @class RTPBaseDCCPIPv4Socket
+ * @short A DCCP/IPv4 socket class targetted at RTP stacks.
+ *
+ * This class provides a flat interface that includes all the services
+ * required by an RTP stack.
+ *
+ * It can be used in two ways:
+ *
+ * To instantiate the DualSocket template, which will be used to
+ * instantiate an RTP stack template (such as TRTPSessionBase).
+ *
+ * To directly instantiate an RTP stack template (such as
+ * TRTPSessionBase).
+ *
+ * This class offers an example of the interface that other classes
+ * should provide in order to specialize the ccRTP stack for different
+ * underlying protocols.
+ *
+ * @author Leandro Sales <leandroal@gmail.com>
+ * @author Ivo Calado <txithihausen@gmail.com>
+ * @author Heverton Stuart <hevertonsns@gmail.com>
+ **/
+class RTPBaseDCCPIPv4Socket: private DCCPSocket {
+public:
+	/**
+	 * Constructor for receiver.
+	 **/
+	RTPBaseDCCPIPv4Socket(const InetAddress& host, tpport_t port) :
+		DCCPSocket((IPV4Host&) host, port) {
+	}
+
+	inline ~RTPBaseDCCPIPv4Socket() {
+		endSocket();
+	}
+
+	inline size_t available() {
+		return DCCPSocket::available();
+	}
+
+	inline bool isPendingRecv(microtimeout_t timeout = 0) {
+		return DCCPSocket::isPendingConnection(timeout);
+	}
+
+	inline InetHostAddress getSender(tpport_t& port) const {
+		return DCCPSocket::getIPV4Sender(&port);
+	}
+
+	inline size_t recv(unsigned char* buffer, size_t len) {
+		size_t av = getNextPacketSize();
+		len = len > av ? av : len;
+		return DCCPSocket::readData((char*) buffer, len);
+	}
+
+	inline void connect(IPV4Host &host, tpport_t port) {
+		return DCCPSocket::connect(host, port);
+	}
+
+	/**
+	 * Get size of next datagram waiting to be read.
+	 **/
+	inline size_t getNextPacketSize() const {
+		size_t len;
+		ccioctl(DCCPSocket::so, FIONREAD, len);
+		return len;
+	}
+
+	Socket::Error setMulticast(bool enable) {
+		return DCCPSocket::setMulticastByFamily(enable);
+	}
+
+	inline Socket::Error join(const IPV4Multicast& host, uint32 iface) {
+		return DCCPSocket::join(host);
+	}
+
+	inline Socket::Error drop(const InetMcastAddress& ia) {
+		return DCCPSocket::drop(ia);
+	}
+
+	inline Socket::Error setTimeToLive(unsigned char ttl) {
+		return DCCPSocket::setTimeToLiveByFamily(ttl);
+	}
+
+	/**
+	 * Constructor for transmitter.
+	 **/
+	RTPBaseDCCPIPv4Socket() :
+		DCCPSocket() {
+	}
+
+	RTPBaseDCCPIPv4Socket(RTPBaseDCCPIPv4Socket& server) :
+		DCCPSocket(server) {
+	}
+
+	inline void setPeer(const InetAddress &ia, tpport_t port) {
+		if (!DCCPSocket::isConnected())
+			DCCPSocket::connect((IPV4Host&) ia, port);
+	}
+
+	inline bool isConnect(void) {
+		return DCCPSocket::isConnected();
+	}
+
+	inline size_t send(const unsigned char* const buffer, size_t len) {
+		DCCPSocket::bufferSize(len);
+		return DCCPSocket::writeData(buffer, len);
+	}
+
+	inline SOCKET getRecvSocket() const {
+		return DCCPSocket::so;
+	}
+
+	// common
+	inline void endSocket() {
+		DCCPSocket::endSocket();
+	}
+};
+
+/**
+ * @class DualRTPChannel
+ * @short A socket class based on two (UDP or DCCP)/IPv4 sockets.
  *
  * Defines a communication channel for RTP data and/or RTCP streams.
  * Sockets used to instantiate this template must define a framing
  * mechanism (UDP does not need any addition, TCP does).
  *
- * This class implements a socket as a pair of UDP/IPv4 sockets,
+ * This class implements a socket as a pair of IPv4 sockets (such sockets
+ * could be UDP or DCCP-based),
  * alllowing both transmission and reception of packets in unicast as
- * well as multicast mode. The implementation of this class relies on
- * the Common C++ UDPSocket class but provides the interface needed by
- * a ccRTP stack.
+ * well as multicast mode (just for UDP). The implementation of this class
+ * relies on the Common C++ UDPSocket and DCCPSocket classes but provides 
+ * the interface needed by a ccRTP stack.
  *
  * Normally, RTP stacks will use two objects of this class, one for
  * RTP data packets transmission/reception and other for RTCP
  * (control) transmission/reception.
  *
  * @author Federico Montesino Pouzols <fedemp@altern.org>
+ * @author Leandro Sales <leandroal@gmail.com>
+ * @author Ivo Calado <txithihausen@gmail.com>
+ * @author Heverton Stuart <hevertonsns@gmail.com>
  **/
 template<class BaseSocket>
 class DualRTPChannel
@@ -193,22 +317,78 @@ public:
 	{ 
 		recvSocket = new BaseSocket(ia,port);
 		sendSocket = new BaseSocket;
+		readData = 0;
 	}
 
 	inline ~DualRTPChannel()
-	{ delete sendSocket; delete recvSocket; }
+	{
+		delete recvSocket;
+		if (dynamic_cast<RTPBaseUDPIPv4Socket*> (sendSocket))
+			delete sendSocket;
+		else
+			for (typename map<AddressPeer*, BaseSocket*>::iterator it =
+					clientsServer.begin(); it != clientsServer.end(); it++) {
+				delete it->first;
+				delete it->second;
+			}
+	}
 	
 	inline bool
-	isPendingRecv(microtimeout_t timeout) const
-	{ return recvSocket->isPendingRecv(timeout); }
+	isPendingRecv(microtimeout_t timeout)
+	{
+		if (dynamic_cast<RTPBaseUDPIPv4Socket*> (recvSocket))
+			return recvSocket->isPendingRecv(timeout);
+		else if (recvSocket->isPendingRecv(timeout)) {
+			BaseSocket* myClientServer = new BaseSocket(*recvSocket);
+			tpport_t port;
+			InetHostAddress myClientServerAddress = myClientServer->getSender(
+					port);
+			AddressPeer* addr = new AddressPeer(
+					(InetAddress) myClientServerAddress, port);
+			clientsServer[addr] = myClientServer;
+			return true;
+		} else {
+			for (typename map<AddressPeer*, BaseSocket*>::iterator it =
+					clientsServer.begin(); it != clientsServer.end(); it++) {
+				RTPBaseDCCPIPv4Socket* ptr =
+						dynamic_cast<RTPBaseDCCPIPv4Socket*> (it->second);
+				if (ptr) {
+					size_t ava = ptr->getNextPacketSize();
+					if (ava > 0) {
+						readData = it->second;
+						return true;
+					}
+				}
+			}
+			return false;
+		}
+
+	}
 
 	inline InetHostAddress
-	getSender(tpport_t& port) const
-	{ return recvSocket->getSender(port); }
+	getSender(tpport_t& port)
+	{
+		if (dynamic_cast<RTPBaseUDPIPv4Socket*> (recvSocket)) {
+			return recvSocket->getSender(port);
+		} else {
+			if (readData)
+				return readData->getSender(port);
+			else {
+				//FIXME: what should we do if the readData is null?
+				readData = clientsServer.begin()->second;
+				return readData->getSender(port);
+			}
+		}
+	}
 
 	inline size_t
 	recv(unsigned char* buffer, size_t len)
-	{ return recvSocket->recv(buffer, len); }
+	{
+		if (dynamic_cast<RTPBaseUDPIPv4Socket*> (recvSocket))
+			return recvSocket->recv(buffer, len);
+		else
+			return readData->recv(buffer, len);
+	}
 
 	inline size_t
 	getNextPacketSize() const
@@ -234,7 +414,31 @@ public:
  
 	inline void 
 	setPeer(const InetAddress& host, tpport_t port)
-	{ sendSocket->setPeer(host,port); }
+	{
+		using namespace std;
+		typename map<AddressPeer*, BaseSocket*>::iterator it;
+
+		if (dynamic_cast<RTPBaseUDPIPv4Socket*> (recvSocket))
+			sendSocket->setPeer(host, port);
+		else {
+			AddressPeer* addr = new AddressPeer(host, port);
+			for (it = clientsServer.begin(); it != clientsServer.end(); it++) {
+				AddressPeer* peer = it->first;
+				if (peer->networkAddress == addr->networkAddress)
+					if (peer->dataPort == addr->dataPort) {
+						sendSocket = it->second;
+						break;
+					}
+			}
+			if (it == clientsServer.end()) {
+				BaseSocket* newSocket = new BaseSocket;
+				newSocket->setPeer(host, port);
+				clientsServer[addr] = newSocket;
+				sendSocket = newSocket;
+			} else
+				delete addr;
+		}
+	}
 
 	inline size_t
 	send(const unsigned char* const buffer, size_t len)		  
@@ -243,14 +447,39 @@ public:
 	inline SOCKET getRecvSocket() const
 	{ return recvSocket->getRecvSocket(); }
 
-	// common.
+
 	inline void
 	endSocket()
-	{ sendSocket->endSocket(); recvSocket->endSocket(); }
+	{
+		sendSocket->endSocket();
+		recvSocket->endSocket();
+		for (typename map<AddressPeer*, BaseSocket*>::iterator it =
+				clientsServer.begin(); it != clientsServer.end(); it++)
+			it->second->endSocket();
+	}
+
+	struct AddressPeer {
+		AddressPeer(InetAddress na, tpport_t dtp) :
+			networkAddress(na), dataPort(dtp) {
+		}
+
+		inline const InetAddress& getNetworkAddress() const {
+			return networkAddress;
+		}
+
+		inline tpport_t getDataPort() const {
+			return dataPort;
+		}
+
+		InetAddress networkAddress;
+		tpport_t dataPort;
+	};
 
 private:
 	BaseSocket* sendSocket;
 	BaseSocket* recvSocket;
+	map<AddressPeer*, BaseSocket*> clientsServer;
+	BaseSocket* readData;
 };
 
 #ifdef	CCXX_IPV6
@@ -349,24 +578,130 @@ public:
 };
 
 /**
- * @class DualUDPIPv6Socket
- * @short A socket class based on two UDP/IPv6 sockets.
+ * @class RTPBaseDCCPIPv6Socket
+ * @short A DCCP/IPv6 socket class targetted at RTP stacks.
+ *
+ * This class provides a flat interface that includes all the services
+ * required by an RTP stack.
+ *
+ * It can be used in two ways:
+ *
+ * To instantiate the DualSocket template, which will be used to
+ * instantiate an RTP stack template (such as TRTPSessionBaseIPV6).
+ *
+ * To directly instantiate an RTP stack template (such as
+ * TRTPSessionBaseIPV6).
+ *
+ * This class offers an example of the interface that other classes
+ * should provide in order to specialize the ccRTP stack for different
+ * underlying protocols.
+ *
+ * @author Leandro Sales <leandroal@gmail.com>
+ * @author Ivo Calado <txithihausen@gmail.com>
+ * @author Heverton Stuart <hevertonsns@gmail.com>
+ **/
+class RTPBaseDCCPIPv6Socket : private DCCPSocket
+{
+public:
+	/**
+	 * Constructor for receiver.
+	 **/
+	RTPBaseDCCPIPv6Socket(const InetAddress& host, tpport_t port) :
+	DCCPSocket((IPV6Host&) host, port) {}
+
+	inline ~RTPBaseDCCPIPv6Socket()
+	{	endSocket();}
+
+	inline size_t available()
+	{	return DCCPSocket::available();}
+
+	inline bool isPendingRecv(microtimeout_t timeout = 0)
+	{	return DCCPSocket::isPendingConnection(timeout);}
+
+	inline IPV6Host getSender(tpport_t& port) const
+	{	return DCCPSocket::getIPV6Sender(&port);}
+
+	inline size_t recv(unsigned char* buffer, size_t len) {
+		size_t av = getNextPacketSize();
+		len = len > av ? av : len;
+		return DCCPSocket::readData((char*) buffer, len);
+	}
+
+	inline void connect(IPV6Host &host, tpport_t port)
+	{	return DCCPSocket::connect(host, port);}
+
+	/**
+	 * Get size of next datagram waiting to be read.
+	 **/
+	inline size_t getNextPacketSize() const
+	{	size_t len; ccioctl(DCCPSocket::so, FIONREAD, len); return len;}
+
+	Socket::Error setMulticast(bool enable)
+	{	return DCCPSocket::setMulticastByFamily(enable);}
+
+	inline Socket::Error join(const IPV6Multicast& host, uint32 iface)
+	{	return DCCPSocket::join(host);}
+
+	inline Socket::Error drop(const InetMcastAddress& ia)
+	{	return DCCPSocket::drop(ia);}
+
+	inline Socket::Error setTimeToLive(unsigned char ttl)
+	{	return DCCPSocket::setTimeToLiveByFamily(ttl);}
+
+	/**
+	 * Constructor for transmitter.
+	 **/
+	RTPBaseDCCPIPv6Socket() :
+	DCCPSocket() {}
+
+	RTPBaseDCCPIPv6Socket(RTPBaseDCCPIPv6Socket& server) :
+	DCCPSocket(server) {}
+
+	inline void setPeer(const InetAddress &ia, tpport_t port) {
+		if (!DCCPSocket::isConnected())
+		DCCPSocket::connect((IPV6Host&) ia, port);
+	}
+
+	inline bool isConnect(void)
+	{	return DCCPSocket::isConnected();}
+
+	inline size_t send(const unsigned char* const buffer, size_t len) {
+		DCCPSocket::bufferSize(len);
+		return DCCPSocket::writeData(buffer, len);
+	}
+
+	inline SOCKET getRecvSocket() const
+	{	return DCCPSocket::so;}
+
+	// common
+	inline void endSocket()
+	{	DCCPSocket::endSocket();}
+
+};
+
+/**
+ * @class DualRTPChannelIPV6
+ * @short A socket class based on two (UDP or DCCP)/IPv6 sockets.
  *
  * Defines a communication channel for RTP data and/or RTCP streams.
  * Sockets used to instantiate this template must define a framing
  * mechanism (UDP does not need any addition, TCP does).
  *
- * This class implements a socket as a pair of UDP/IPv6 sockets,
+ * This class implements a socket as a pair of IPv6 sockets (such sockets
+ * could be UDP or DCCP-based),
  * alllowing both transmission and reception of packets in unicast as
- * well as multicast mode. The implementation of this class relies on
- * the Common C++ UDPSocket class but provides the interface needed by
- * a ccRTP stack.
+ * well as multicast mode (just for UDP). The implementation of this class
+ * relies on the Common C++ UDPSocket and DCCPSocket classes but provides 
+ * the interface needed by a ccRTP stack.
  *
  * Normally, RTP stacks will use two objects of this class, one for
  * RTP data packets transmission/reception and other for RTCP
  * (control) transmission/reception.
  *
  * @author David Sugar <dyfet@gnutelephony.org>
+ * @author Leandro Sales <leandroal@gmail.com>
+ * @author Ivo Calado <txithihausen@gmail.com>
+ * @author Heverton Stuart <hevertonsns@gmail.com>
  **/
 template<class BaseSocket>
 class DualRTPChannelIPV6
@@ -376,22 +711,78 @@ public:
 	{ 
 		recvSocket = new BaseSocket(ia,port);
 		sendSocket = new BaseSocket;
+		readData = 0;
 	}
 
 	inline ~DualRTPChannelIPV6()
-	{ delete sendSocket; delete recvSocket; }
+	{
+		delete recvSocket;
+		if (dynamic_cast<RTPBaseUDPIPv4Socket*> (sendSocket))
+			delete sendSocket;
+		else
+			for (typename map<AddressPeer*, BaseSocket*>::iterator it =
+				clientsServer.begin(); it != clientsServer.end(); it++) {
+				delete it->first;
+				delete it->second;
+			}
+	}
 	
 	inline bool
-	isPendingRecv(microtimeout_t timeout) const
-	{ return recvSocket->isPendingRecv(timeout); }
+	isPendingRecv(microtimeout_t timeout)
+	{
+		if (dynamic_cast<RTPBaseUDPIPv6Socket*> (recvSocket))
+			return recvSocket->isPendingRecv(timeout);
+		else if (recvSocket->isPendingRecv(timeout)) {
+			BaseSocket* myClientServer = new BaseSocket(*recvSocket);
+			tpport_t port;
+			InetHostAddress myClientServerAddress = myClientServer->getSender(port);
+			AddressPeer* addr = new AddressPeer((InetAddress) myClientServerAddress, port);
+			clientsServer[addr] = myClientServer;
+			return true;
+		} else {
+			for (typename map<AddressPeer*, BaseSocket*>::iterator it =
+					clientsServer.begin(); it != clientsServer.end(); it++) {
+				RTPBaseDCCPIPv4Socket* ptr =
+				dynamic_cast<RTPBaseDCCPIPv6Socket*> (it->second);
+				if (ptr)
+				{
+					size_t ava = ptr->getNextPacketSize();
+					if (ava > 0) {
+						readData = it->second;
+						return true;
+					}
+				}
+			}
+			return false;
+		}
+	}
 
 	inline IPV6Host
-	getSender(tpport_t& port) const
-	{ return recvSocket->getIPV6Sender(port); }
+	getSender(tpport_t& port)
+	{
+		if (dynamic_cast<RTPBaseUDPIPv6Socket*> (recvSocket)) {
+			return recvSocket->getIPV6Sender(port);
+		} else {
+			if (readData)
+				return readData->getIPV6Sender(port);
+			else
+			{
+				//FIXME: what should we do if the readData is null?
+				readData = clientsServer.begin()->second;
+				return readData->getSender(port);
+			}
+
+		}
+	}
 
 	inline size_t
 	recv(unsigned char* buffer, size_t len)
-	{ return recvSocket->recv(buffer, len); }
+	{
+		if (dynamic_cast<RTPBaseUDPIPv6Socket*> (recvSocket))
+			return recvSocket->recv(buffer, len);
+		else
+			return readData->recv(buffer, len);
+	}
 
 	inline size_t
 	getNextPacketSize() const
@@ -417,7 +808,34 @@ public:
  
 	inline void 
 	setPeer(const IPV6Host& host, tpport_t port)
-	{ sendSocket->setPeer(host,port); }
+	{
+		using namespace std;
+		typename map<AddressPeer*, BaseSocket*>::iterator it;
+
+		if (dynamic_cast<RTPBaseUDPIPv6Socket*> (recvSocket))
+			sendSocket->setPeer(host, port);
+		else {
+			AddressPeer* addr = new AddressPeer(host, port);
+			for (it = clientsServer.begin(); it != clientsServer.end(); it++) {
+				AddressPeer* peer = it->first;
+				if (peer->networkAddress == addr->networkAddress)
+					if (peer->dataPort == addr->dataPort)
+					{
+						sendSocket = it->second;
+						break;
+					}
+			}
+			if (it == clientsServer.end())
+			{
+				BaseSocket* newSocket = new BaseSocket;
+				newSocket->setPeer(host, port);
+				clientsServer[addr] = newSocket;
+				sendSocket = newSocket;
+			}
+			else
+				delete addr;
+		}
+	}
 
 	inline size_t
 	send(const unsigned char* const buffer, size_t len)		  
@@ -426,14 +844,39 @@ public:
 	inline SOCKET getRecvSocket() const
 	{ return recvSocket->getRecvSocket(); }
 
-	// common.
+
 	inline void
 	endSocket()
-	{ sendSocket->endSocket(); recvSocket->endSocket(); }
+	{
+		sendSocket->endSocket();
+		recvSocket->endSocket();
+		for (typename map<AddressPeer*, BaseSocket*>::iterator it =
+				clientsServer.begin(); it != clientsServer.end(); it++)
+			it->second->endSocket();
+	}
+
+	struct AddressPeer {
+		AddressPeer(InetAddress na, tpport_t dtp) :
+		networkAddress(na), dataPort(dtp) {
+		}
+
+		inline const InetAddress& getNetworkAddress() const {
+			return networkAddress;
+		}
+
+		inline tpport_t getDataPort() const {
+			return dataPort;
+		}
+
+		InetAddress networkAddress;
+		tpport_t dataPort;
+	};
 
 private:
 	BaseSocket* sendSocket;
 	BaseSocket* recvSocket;
+	map<AddressPeer*, BaseSocket*> clientsServer;
+	BaseSocket* readData;
 };
 
 
@@ -441,9 +884,14 @@ typedef DualRTPChannelIPV6<RTPBaseUDPIPv
 typedef	RTPBaseUDPIPv6Socket SingleRTPChannelIPV6;
 typedef SingleRTPChannelIPV6 SymmetricRTPChannelIPV6;
 
+typedef DualRTPChannelIPV6<RTPBaseDCCPIPv6Socket> DualRTPDCCPIPv6Channel;
+typedef RTPBaseDCCPIPv6Socket SingleRTPDCCPChannelIPV6;
+typedef SingleRTPDCCPChannelIPV6 SymmetricRTPDCCPChannelIPV6;
+
 #endif
 
 typedef DualRTPChannel<RTPBaseUDPIPv4Socket> DualRTPUDPIPv4Channel;
+typedef DualRTPChannel<RTPBaseDCCPIPv4Socket> DualRTPDCCPIPv4Channel;
 
 /**
  * May be used in applications where using the same socket for both
@@ -452,10 +900,21 @@ typedef DualRTPChannel<RTPBaseUDPIPv4Soc
 typedef RTPBaseUDPIPv4Socket SingleRTPChannel;
 
 /**
+ * May be used in applications where using the same DCCP socket for both
+ * sending and receiving is not a limitation.
+ **/
+typedef RTPBaseDCCPIPv4Socket SingleRTPDCCPChannel;
+
+/**
  * Actually, RTP with a single channel can be called 'Symmetric RTP'
  **/
 typedef SingleRTPChannel SymmetricRTPChannel;
 
+/**
+ * Actually, RTP with a single channel using DCCP transport protocol can be called 'Symmetric RTP-DCCP'
+ **/
+typedef SingleRTPDCCPChannel SymmetricRTPDCCPChannel;
+
 /** @}*/ // sockets
 
 #ifdef  CCXX_NAMESPACES
diff -uprN ccrtp/src/ccrtp/rtp.h ccrtp_dccp/src/ccrtp/rtp.h
--- ccrtp/src/ccrtp/rtp.h	2009-09-01 15:36:08.000000000 -0300
+++ ccrtp_dccp/src/ccrtp/rtp.h	2009-09-01 15:37:23.000000000 -0300
@@ -606,6 +606,7 @@ inline size_t dispatchBYE(const std::str
  * @short UDP/IPv4 RTP Session scheduled by one thread of execution.
  **/
 typedef SingleThreadRTPSession<> RTPSession;
+typedef SingleThreadRTPSession<DualRTPDCCPIPv4Channel, DualRTPDCCPIPv4Channel, AVPQueue> RTPDCCPSession;
 
 /**
  * @typedef RTPSocket
