qrtplib: file cleanup

This commit is contained in:
f4exb 2018-03-05 21:27:06 +01:00
parent 914b8a4d97
commit 915b865e6a
23 changed files with 0 additions and 8255 deletions

View File

@ -19,12 +19,8 @@ set (qrtplib_HEADERS
rtpdefines.h
rtpendian.h
rtperrors.h
rtphashtable.h
rtpinternalsourcedata.h
# rtpipv4address.h
# rtpipv4destination.h
rtpkeyhashtable.h
rtplibraryversion.h
rtppacket.h
rtppacketbuilder.h
rtprandom.h
@ -43,14 +39,7 @@ set (qrtplib_HEADERS
rtptypes_win.h
rtptypes.h
rtpudptransmitter.h
# rtpudpv4transmitter.h
# rtpudpv4transmitternobind.h
# rtpexternaltransmitter.h
rtpsocketutil.h
rtpabortdescriptors.h
rtpselect.h
# rtptcpaddress.h
# rtptcptransmitter.h
)
set(qrtplib_SOURCES
@ -68,9 +57,6 @@ set(qrtplib_SOURCES
rtpcollisionlist.cpp
rtperrors.cpp
rtpinternalsourcedata.cpp
# rtpipv4address.cpp
# rtpipv4destination.cpp
rtplibraryversion.cpp
rtppacket.cpp
rtppacketbuilder.cpp
rtprandom.cpp
@ -84,12 +70,6 @@ set(qrtplib_SOURCES
rtpsources.cpp
rtptimeutilities.cpp
rtpudptransmitter.cpp
# rtpudpv4transmitter.cpp
# rtpudpv4transmitternobind.cpp
# rtpexternaltransmitter.cpp
rtpabortdescriptors.cpp
# rtptcpaddress.cpp
# rtptcptransmitter.cpp
)
include_directories(

View File

@ -40,10 +40,7 @@ HEADERS += $$PWD/rtcpapppacket.h \
$$PWD/rtpdefines.h \
$$PWD/rtpendian.h \
$$PWD/rtperrors.h \
$$PWD/rtphashtable.h \
$$PWD/rtpinternalsourcedata.h \
$$PWD/rtpkeyhashtable.h \
$$PWD/rtplibraryversion.h \
$$PWD/rtppacket.h \
$$PWD/rtppacketbuilder.h \
$$PWD/rtprandom.h \
@ -80,7 +77,6 @@ SOURCES += $$PWD/rtcpapppacket.cpp \
$$PWD/rtpcollisionlist.cpp \
$$PWD/rtperrors.cpp \
$$PWD/rtpinternalsourcedata.cpp \
$$PWD/rtplibraryversion.cpp \
$$PWD/rtppacket.cpp \
$$PWD/rtppacketbuilder.cpp \
$$PWD/rtprandom.cpp \

View File

@ -1,258 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
#include "rtpabortdescriptors.h"
#include "rtpsocketutilinternal.h"
#include "rtperrors.h"
#include "rtpselect.h"
namespace qrtplib
{
RTPAbortDescriptors::RTPAbortDescriptors()
{
m_descriptors[0] = RTPSOCKERR;
m_descriptors[1] = RTPSOCKERR;
m_init = false;
}
RTPAbortDescriptors::~RTPAbortDescriptors()
{
Destroy();
}
#ifdef RTP_SOCKETTYPE_WINSOCK
int RTPAbortDescriptors::Init()
{
if (m_init)
return ERR_RTP_ABORTDESC_ALREADYINIT;
SOCKET listensock;
int size;
struct sockaddr_in addr;
listensock = socket(PF_INET,SOCK_STREAM,0);
if (listensock == RTPSOCKERR)
return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS;
memset(&addr,0,sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
if (bind(listensock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0)
{
RTPCLOSE(listensock);
return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS;
}
memset(&addr,0,sizeof(struct sockaddr_in));
size = sizeof(struct sockaddr_in);
if (getsockname(listensock,(struct sockaddr*)&addr,&size) != 0)
{
RTPCLOSE(listensock);
return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS;
}
unsigned short connectport = ntohs(addr.sin_port);
m_descriptors[0] = socket(PF_INET,SOCK_STREAM,0);
if (m_descriptors[0] == RTPSOCKERR)
{
RTPCLOSE(listensock);
return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS;
}
memset(&addr,0,sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
if (bind(m_descriptors[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0)
{
RTPCLOSE(listensock);
RTPCLOSE(m_descriptors[0]);
return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS;
}
if (listen(listensock,1) != 0)
{
RTPCLOSE(listensock);
RTPCLOSE(m_descriptors[0]);
return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS;
}
memset(&addr,0,sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(connectport);
if (connect(m_descriptors[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0)
{
RTPCLOSE(listensock);
RTPCLOSE(m_descriptors[0]);
return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS;
}
memset(&addr,0,sizeof(struct sockaddr_in));
size = sizeof(struct sockaddr_in);
m_descriptors[1] = accept(listensock,(struct sockaddr *)&addr,&size);
if (m_descriptors[1] == RTPSOCKERR)
{
RTPCLOSE(listensock);
RTPCLOSE(m_descriptors[0]);
return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS;
}
// okay, got the connection, close the listening socket
RTPCLOSE(listensock);
m_init = true;
return 0;
}
void RTPAbortDescriptors::Destroy()
{
if (!m_init)
return;
RTPCLOSE(m_descriptors[0]);
RTPCLOSE(m_descriptors[1]);
m_descriptors[0] = RTPSOCKERR;
m_descriptors[1] = RTPSOCKERR;
m_init = false;
}
int RTPAbortDescriptors::SendAbortSignal()
{
if (!m_init)
return ERR_RTP_ABORTDESC_NOTINIT;
send(m_descriptors[1],"*",1,0);
return 0;
}
int RTPAbortDescriptors::ReadSignallingByte()
{
if (!m_init)
return ERR_RTP_ABORTDESC_NOTINIT;
char buf[1];
recv(m_descriptors[0],buf,1,0);
return 0;
}
#else // unix-style
int RTPAbortDescriptors::Init()
{
if (m_init)
return ERR_RTP_ABORTDESC_ALREADYINIT;
if (pipe(m_descriptors) < 0)
return ERR_RTP_ABORTDESC_CANTCREATEPIPE;
m_init = true;
return 0;
}
void RTPAbortDescriptors::Destroy()
{
if (!m_init)
return;
close(m_descriptors[0]);
close(m_descriptors[1]);
m_descriptors[0] = RTPSOCKERR;
m_descriptors[1] = RTPSOCKERR;
m_init = false;
}
int RTPAbortDescriptors::SendAbortSignal()
{
if (!m_init)
return ERR_RTP_ABORTDESC_NOTINIT;
if (write(m_descriptors[1], "*", 1))
{
// To get rid of __wur related compiler warnings
}
return 0;
}
int RTPAbortDescriptors::ReadSignallingByte()
{
if (!m_init)
return ERR_RTP_ABORTDESC_NOTINIT;
unsigned char buf[1];
if (read(m_descriptors[0], buf, 1))
{
// To get rid of __wur related compiler warnings
}
return 0;
}
#endif // RTP_SOCKETTYPE_WINSOCK
// Keep calling 'ReadSignallingByte' until there's no byte left
int RTPAbortDescriptors::ClearAbortSignal()
{
if (!m_init)
return ERR_RTP_ABORTDESC_NOTINIT;
bool done = false;
while (!done)
{
int8_t isset = 0;
// Not used: struct timeval tv = { 0, 0 };
int status = RTPSelect(&m_descriptors[0], &isset, 1, RTPTime(0));
if (status < 0)
return status;
if (!isset)
done = true;
else
{
int status = ReadSignallingByte();
if (status < 0)
return status;
}
}
return 0;
}
} // end namespace

View File

@ -1,111 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtpabortdescriptors.h
*/
#ifndef RTPABORTDESCRIPTORS_H
#define RTPABORTDESCRIPTORS_H
#include "rtpconfig.h"
#include "rtpsocketutil.h"
#include "util/export.h"
namespace qrtplib
{
/**
* Helper class for several RTPTransmitter instances, to be able to cancel a
* call to 'select', 'poll' or 'WSAPoll'.
*
* This is a helper class for several RTPTransmitter instances. Typically a
* call to 'select' (or 'poll' or 'WSAPoll', depending on the platform) is used
* to wait for incoming data for a certain time. To be able to cancel this wait
* from another thread, this class provides a socket descriptor that's compatible
* with e.g. the 'select' call, and to which data can be sent using
* RTPAbortDescriptors::SendAbortSignal. If the descriptor is included in the
* 'select' call, the function will detect incoming data and the function stops
* waiting for incoming data.
*
* The class can be useful in case you'd like to create an implementation which
* uses a single poll thread for several RTPSession and RTPTransmitter instances.
* This idea is further illustrated in `example8.cpp`.
*/
class QRTPLIB_API RTPAbortDescriptors
{
public:
RTPAbortDescriptors();
~RTPAbortDescriptors();
/** Initializes this instance. */
int Init();
/** Returns the socket descriptor that can be included in a call to
* 'select' (for example).*/
SocketType GetAbortSocket() const
{
return m_descriptors[0];
}
/** Returns a flag indicating if this instance was initialized. */
bool IsInitialized() const
{
return m_init;
}
/** De-initializes this instance. */
void Destroy();
/** Send a signal to the socket that's returned by RTPAbortDescriptors::GetAbortSocket,
* causing the 'select' call to detect that data is available, making the call
* end. */
int SendAbortSignal();
/** For each RTPAbortDescriptors::SendAbortSignal function that's called, a call
* to this function can be made to clear the state again. */
int ReadSignallingByte();
/** Similar to ReadSignallingByte::ReadSignallingByte, this function clears the signalling
* state, but this also works independently from the amount of times that
* RTPAbortDescriptors::SendAbortSignal was called. */
int ClearAbortSignal();
private:
SocketType m_descriptors[2];
bool m_init;
};
} // end namespace
#endif // RTPABORTDESCRIPTORS_H

View File

@ -1,634 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
#include "rtpexternaltransmitter.h"
#include "rtprawpacket.h"
#include "rtptimeutilities.h"
#include "rtpdefines.h"
#include "rtperrors.h"
#include "rtpsocketutilinternal.h"
#include "rtpselect.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
namespace qrtplib
{
RTPExternalTransmitter::RTPExternalTransmitter() :
packetinjector((RTPExternalTransmitter *) this)
{
created = false;
init = false;
}
RTPExternalTransmitter::~RTPExternalTransmitter()
{
Destroy();
}
int RTPExternalTransmitter::Init(bool tsafe)
{
if (init)
return ERR_RTP_EXTERNALTRANS_ALREADYINIT;
if (tsafe)
return ERR_RTP_NOTHREADSUPPORT;
init = true;
return 0;
}
int RTPExternalTransmitter::Create(std::size_t maximumpacketsize, const RTPTransmissionParams *transparams)
{
const RTPExternalTransmissionParams *params;
int status;
if (!init)
return ERR_RTP_EXTERNALTRANS_NOTINIT;
if (created)
{
return ERR_RTP_EXTERNALTRANS_ALREADYCREATED;
}
// Obtain transmission parameters
if (transparams == 0)
{
return ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS;
}
if (transparams->GetTransmissionProtocol() != RTPTransmitter::ExternalProto)
{
return ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS;
}
params = (const RTPExternalTransmissionParams *) transparams;
if ((status = m_abortDesc.Init()) < 0)
{
return status;
}
m_abortCount = 0;
maxpacksize = maximumpacketsize;
sender = params->GetSender();
headersize = params->GetAdditionalHeaderSize();
localhostname = 0;
localhostnamelength = 0;
waitingfordata = false;
created = true;
return 0;
}
void RTPExternalTransmitter::Destroy()
{
if (!init)
return;
if (!created)
{
return;
}
if (localhostname)
{
delete[] localhostname;
localhostname = 0;
localhostnamelength = 0;
}
FlushPackets();
created = false;
if (waitingfordata)
{
m_abortDesc.SendAbortSignal();
m_abortCount++;
m_abortDesc.Destroy();
// to make sure that the WaitForIncomingData function ended
}
else
m_abortDesc.Destroy();
}
RTPTransmissionInfo *RTPExternalTransmitter::GetTransmissionInfo()
{
if (!init)
return 0;
RTPTransmissionInfo *tinf = new RTPExternalTransmissionInfo(&packetinjector);
return tinf;
}
void RTPExternalTransmitter::DeleteTransmissionInfo(RTPTransmissionInfo *i)
{
if (!init)
return;
delete i;
}
int RTPExternalTransmitter::GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength)
{
if (!init)
return ERR_RTP_EXTERNALTRANS_NOTINIT;
if (!created)
{
return ERR_RTP_EXTERNALTRANS_NOTCREATED;
}
if (localhostname == 0)
{
// We'll just use 'gethostname' for simplicity
char name[1024];
if (gethostname(name, 1023) != 0)
strcpy(name, "localhost"); // failsafe
else
name[1023] = 0; // ensure null-termination
localhostnamelength = strlen(name);
localhostname = new uint8_t[localhostnamelength + 1];
memcpy(localhostname, name, localhostnamelength);
localhostname[localhostnamelength] = 0;
}
if ((*bufferlength) < localhostnamelength)
{
*bufferlength = localhostnamelength; // tell the application the required size of the buffer
return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL;
}
memcpy(buffer, localhostname, localhostnamelength);
*bufferlength = localhostnamelength;
return 0;
}
bool RTPExternalTransmitter::ComesFromThisTransmitter(const RTPAddress *addr)
{
bool value = false;
if (sender)
value = sender->ComesFromThisSender(addr);
return value;
}
int RTPExternalTransmitter::Poll()
{
return 0;
}
int RTPExternalTransmitter::WaitForIncomingData(const RTPTime &delay, bool *dataavailable)
{
if (!init)
return ERR_RTP_EXTERNALTRANS_NOTINIT;
if (!created)
{
return ERR_RTP_EXTERNALTRANS_NOTCREATED;
}
if (waitingfordata)
{
return ERR_RTP_EXTERNALTRANS_ALREADYWAITING;
}
waitingfordata = true;
if (!rawpacketlist.empty())
{
if (dataavailable != 0)
*dataavailable = true;
waitingfordata = false;
return 0;
}
int8_t isset = 0;
SocketType abortSock = m_abortDesc.GetAbortSocket();
int status = RTPSelect(&abortSock, &isset, 1, delay);
if (status < 0)
{
waitingfordata = false;
return status;
}
waitingfordata = false;
if (!created) // destroy called
{
return 0;
}
// if aborted, read from abort buffer
if (isset)
{
m_abortDesc.ClearAbortSignal();
m_abortCount = 0;
}
if (dataavailable != 0)
{
if (rawpacketlist.empty())
*dataavailable = false;
else
*dataavailable = true;
}
return 0;
}
int RTPExternalTransmitter::AbortWait()
{
if (!init)
return ERR_RTP_EXTERNALTRANS_NOTINIT;
if (!created)
{
return ERR_RTP_EXTERNALTRANS_NOTCREATED;
}
if (!waitingfordata)
{
return ERR_RTP_EXTERNALTRANS_NOTWAITING;
}
m_abortDesc.SendAbortSignal();
m_abortCount++;
return 0;
}
int RTPExternalTransmitter::SendRTPData(const void *data, std::size_t len)
{
if (!init)
return ERR_RTP_EXTERNALTRANS_NOTINIT;
if (!created)
{
return ERR_RTP_EXTERNALTRANS_NOTCREATED;
}
if (len > maxpacksize)
{
return ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG;
}
if (!sender)
{
return ERR_RTP_EXTERNALTRANS_NOSENDER;
}
if (!sender->SendRTP(data, len))
return ERR_RTP_EXTERNALTRANS_SENDERROR;
return 0;
}
int RTPExternalTransmitter::SendRTCPData(const void *data, std::size_t len)
{
if (!init)
return ERR_RTP_EXTERNALTRANS_NOTINIT;
if (!created)
{
return ERR_RTP_EXTERNALTRANS_NOTCREATED;
}
if (len > maxpacksize)
{
return ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG;
}
if (!sender)
{
return ERR_RTP_EXTERNALTRANS_NOSENDER;
}
if (!sender->SendRTCP(data, len))
return ERR_RTP_EXTERNALTRANS_SENDERROR;
return 0;
}
int RTPExternalTransmitter::AddDestination(const RTPAddress &)
{
return ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED;
}
int RTPExternalTransmitter::DeleteDestination(const RTPAddress &)
{
return ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED;
}
void RTPExternalTransmitter::ClearDestinations()
{
}
bool RTPExternalTransmitter::SupportsMulticasting()
{
return false;
}
int RTPExternalTransmitter::JoinMulticastGroup(const RTPAddress &)
{
return ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT;
}
int RTPExternalTransmitter::LeaveMulticastGroup(const RTPAddress &)
{
return ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT;
}
void RTPExternalTransmitter::LeaveAllMulticastGroups()
{
}
int RTPExternalTransmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m)
{
if (!init)
return ERR_RTP_EXTERNALTRANS_NOTINIT;
if (!created)
{
return ERR_RTP_EXTERNALTRANS_NOTCREATED;
}
if (m != RTPTransmitter::AcceptAll)
{
return ERR_RTP_EXTERNALTRANS_BADRECEIVEMODE;
}
return 0;
}
int RTPExternalTransmitter::AddToIgnoreList(const RTPAddress &)
{
return ERR_RTP_EXTERNALTRANS_NOIGNORELIST;
}
int RTPExternalTransmitter::DeleteFromIgnoreList(const RTPAddress &)
{
return ERR_RTP_EXTERNALTRANS_NOIGNORELIST;
}
void RTPExternalTransmitter::ClearIgnoreList()
{
}
int RTPExternalTransmitter::AddToAcceptList(const RTPAddress &)
{
return ERR_RTP_EXTERNALTRANS_NOACCEPTLIST;
}
int RTPExternalTransmitter::DeleteFromAcceptList(const RTPAddress &)
{
return ERR_RTP_EXTERNALTRANS_NOACCEPTLIST;
}
void RTPExternalTransmitter::ClearAcceptList()
{
}
int RTPExternalTransmitter::SetMaximumPacketSize(std::size_t s)
{
if (!init)
return ERR_RTP_EXTERNALTRANS_NOTINIT;
if (!created)
{
return ERR_RTP_EXTERNALTRANS_NOTCREATED;
}
maxpacksize = s;
return 0;
}
bool RTPExternalTransmitter::NewDataAvailable()
{
if (!init)
return false;
bool v;
if (!created)
v = false;
else
{
if (rawpacketlist.empty())
v = false;
else
v = true;
}
return v;
}
RTPRawPacket *RTPExternalTransmitter::GetNextPacket()
{
if (!init)
return 0;
RTPRawPacket *p;
if (!created)
{
return 0;
}
if (rawpacketlist.empty())
{
return 0;
}
p = *(rawpacketlist.begin());
rawpacketlist.pop_front();
return p;
}
// Here the private functions start...
void RTPExternalTransmitter::FlushPackets()
{
std::list<RTPRawPacket*>::const_iterator it;
for (it = rawpacketlist.begin(); it != rawpacketlist.end(); ++it)
delete *it;
rawpacketlist.clear();
}
void RTPExternalTransmitter::InjectRTP(const void *data, std::size_t len, const RTPAddress &a)
{
if (!init)
return;
if (!created)
{
return;
}
RTPAddress *addr = a.CreateCopy();
if (addr == 0)
return;
uint8_t *datacopy;
datacopy = new uint8_t[len];
if (datacopy == 0)
{
delete addr;
return;
}
memcpy(datacopy, data, len);
RTPTime curtime = RTPTime::CurrentTime();
RTPRawPacket *pack;
pack = new RTPRawPacket(datacopy, len, addr, curtime, true);
if (pack == 0)
{
delete addr;
delete[] localhostname;
return;
}
rawpacketlist.push_back(pack);
if (m_abortCount == 0)
{
m_abortDesc.SendAbortSignal();
m_abortCount++;
}
}
void RTPExternalTransmitter::InjectRTCP(const void *data, std::size_t len, const RTPAddress &a)
{
if (!init)
return;
if (!created)
{
return;
}
RTPAddress *addr = a.CreateCopy();
if (addr == 0)
return;
uint8_t *datacopy;
datacopy = new uint8_t[len];
if (datacopy == 0)
{
delete addr;
return;
}
memcpy(datacopy, data, len);
RTPTime curtime = RTPTime::CurrentTime();
RTPRawPacket *pack;
pack = new RTPRawPacket(datacopy, len, addr, curtime, false);
if (pack == 0)
{
delete addr;
delete[] localhostname;
return;
}
rawpacketlist.push_back(pack);
if (m_abortCount == 0)
{
m_abortDesc.SendAbortSignal();
m_abortCount++;
}
}
void RTPExternalTransmitter::InjectRTPorRTCP(const void *data, std::size_t len, const RTPAddress &a)
{
if (!init)
return;
if (!created)
{
return;
}
RTPAddress *addr = a.CreateCopy();
if (addr == 0)
return;
uint8_t *datacopy;
bool rtp = true;
if (len >= 2)
{
const uint8_t *pData = (const uint8_t *) data;
if (pData[1] >= 200 && pData[1] <= 204)
rtp = false;
}
datacopy = new uint8_t[len];
if (datacopy == 0)
{
delete addr;
return;
}
memcpy(datacopy, data, len);
RTPTime curtime = RTPTime::CurrentTime();
RTPRawPacket *pack;
pack = new RTPRawPacket(datacopy, len, addr, curtime, rtp);
if (pack == 0)
{
delete addr;
delete[] localhostname;
return;
}
rawpacketlist.push_back(pack);
if (m_abortCount == 0)
{
m_abortDesc.SendAbortSignal();
m_abortCount++;
}
}
} // end namespace

View File

@ -1,254 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtpexternaltransmitter.h
*/
#ifndef RTPEXTERNALTRANSMITTER_H
#define RTPEXTERNALTRANSMITTER_H
#include "rtpconfig.h"
#include "rtptransmitter.h"
#include "rtpabortdescriptors.h"
#include <list>
#include "util/export.h"
namespace qrtplib
{
class RTPExternalTransmitter;
/** Base class to specify a mechanism to transmit RTP packets outside of this library.
* Base class to specify a mechanism to transmit RTP packets outside of this library. When
* you want to use your own mechanism to transmit RTP packets, you need to specify that
* you'll be using the external transmission component, and derive a class from this base
* class. An instance should then be specified in the RTPExternalTransmissionParams object,
* so that the transmitter will call the \c SendRTP, \c SendRTCP and \c ComesFromThisSender
* methods of this instance when needed.
*/
class QRTPLIB_API RTPExternalSender
{
public:
RTPExternalSender()
{
}
virtual ~RTPExternalSender()
{
}
/** This member function will be called when RTP data needs to be transmitted. */
virtual bool SendRTP(const void *data, std::size_t len) = 0;
/** This member function will be called when an RTCP packet needs to be transmitted. */
virtual bool SendRTCP(const void *data, std::size_t len) = 0;
/** Used to identify if an RTPAddress instance originated from this sender (to be able to detect own packets). */
virtual bool ComesFromThisSender(const RTPAddress *a) = 0;
};
/** Interface to inject incoming RTP and RTCP packets into the library.
* Interface to inject incoming RTP and RTCP packets into the library. When you have your own
* mechanism to receive incoming RTP/RTCP data, you'll need to pass these packets to the library.
* By first retrieving the RTPExternalTransmissionInfo instance for the external transmitter you'll
* be using, you can obtain the associated RTPExternalPacketInjecter instance. By calling it's
* member functions, you can then inject RTP or RTCP data into the library for further processing.
*/
class RTPExternalPacketInjecter
{
public:
RTPExternalPacketInjecter(RTPExternalTransmitter *trans)
{
transmitter = trans;
}
~RTPExternalPacketInjecter()
{
}
/** This function can be called to insert an RTP packet into the transmission component. */
void InjectRTP(const void *data, std::size_t len, const RTPAddress &a);
/** This function can be called to insert an RTCP packet into the transmission component. */
void InjectRTCP(const void *data, std::size_t len, const RTPAddress &a);
/** Use this function to inject an RTP or RTCP packet and the transmitter will try to figure out which type of packet it is. */
void InjectRTPorRTCP(const void *data, std::size_t len, const RTPAddress &a);
private:
RTPExternalTransmitter *transmitter;
};
/** Parameters to initialize a transmitter of type RTPExternalTransmitter. */
class RTPExternalTransmissionParams: public RTPTransmissionParams
{
public:
/** Using this constructor you can specify which RTPExternalSender object you'll be using
* and how much the additional header overhead for each packet will be. */
RTPExternalTransmissionParams(RTPExternalSender *s, int headeroverhead) :
RTPTransmissionParams(RTPTransmitter::ExternalProto)
{
sender = s;
headersize = headeroverhead;
}
RTPExternalSender *GetSender() const
{
return sender;
}
int GetAdditionalHeaderSize() const
{
return headersize;
}
private:
RTPExternalSender *sender;
int headersize;
};
/** Additional information about the external transmission component. */
class RTPExternalTransmissionInfo: public RTPTransmissionInfo
{
public:
RTPExternalTransmissionInfo(RTPExternalPacketInjecter *p) :
RTPTransmissionInfo(RTPTransmitter::ExternalProto)
{
packetinjector = p;
}
/** Tells you which RTPExternalPacketInjecter you need to use to pass RTP or RTCP
* data on to the transmission component. */
RTPExternalPacketInjecter *GetPacketInjector() const
{
return packetinjector;
}
private:
RTPExternalPacketInjecter *packetinjector;
};
/** A transmission component which will use user specified functions to transmit the data and
* which will expose functions to inject received RTP or RTCP data into this component.
* A transmission component which will use user specified functions to transmit the data and
* which will expose functions to inject received RTP or RTCP data into this component. Use
* a class derived from RTPExternalSender to specify the functions which need to be used for
* sending the data. Obtain the RTPExternalTransmissionInfo object associated with this
* transmitter to obtain the functions needed to pass RTP/RTCP packets on to the transmitter.
*/
class RTPExternalTransmitter: public RTPTransmitter
{
public:
RTPExternalTransmitter();
~RTPExternalTransmitter();
int Init(bool treadsafe);
int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams);
void Destroy();
RTPTransmissionInfo *GetTransmissionInfo();
void DeleteTransmissionInfo(RTPTransmissionInfo *inf);
int GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength);
bool ComesFromThisTransmitter(const RTPAddress *addr);
std::size_t GetHeaderOverhead()
{
return headersize;
}
int Poll();
int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0);
int AbortWait();
int SendRTPData(const void *data, std::size_t len);
int SendRTCPData(const void *data, std::size_t len);
int AddDestination(const RTPAddress &addr);
int DeleteDestination(const RTPAddress &addr);
void ClearDestinations();
bool SupportsMulticasting();
int JoinMulticastGroup(const RTPAddress &addr);
int LeaveMulticastGroup(const RTPAddress &addr);
void LeaveAllMulticastGroups();
int SetReceiveMode(RTPTransmitter::ReceiveMode m);
int AddToIgnoreList(const RTPAddress &addr);
int DeleteFromIgnoreList(const RTPAddress &addr);
void ClearIgnoreList();
int AddToAcceptList(const RTPAddress &addr);
int DeleteFromAcceptList(const RTPAddress &addr);
void ClearAcceptList();
int SetMaximumPacketSize(std::size_t s);
bool NewDataAvailable();
RTPRawPacket *GetNextPacket();
void InjectRTP(const void *data, std::size_t len, const RTPAddress &a);
void InjectRTCP(const void *data, std::size_t len, const RTPAddress &a);
void InjectRTPorRTCP(const void *data, std::size_t len, const RTPAddress &a);
private:
void FlushPackets();
bool init;
bool created;
bool waitingfordata;
RTPExternalSender *sender;
RTPExternalPacketInjecter packetinjector;
std::list<RTPRawPacket*> rawpacketlist;
uint8_t *localhostname;
std::size_t localhostnamelength;
std::size_t maxpacksize;
int headersize;
RTPAbortDescriptors m_abortDesc;
int m_abortCount;
};
inline void RTPExternalPacketInjecter::InjectRTP(const void *data, std::size_t len, const RTPAddress &a)
{
transmitter->InjectRTP(data, len, a);
}
inline void RTPExternalPacketInjecter::InjectRTCP(const void *data, std::size_t len, const RTPAddress &a)
{
transmitter->InjectRTCP(data, len, a);
}
inline void RTPExternalPacketInjecter::InjectRTPorRTCP(const void *data, std::size_t len, const RTPAddress &a)
{
transmitter->InjectRTPorRTCP(data, len, a);
}
} // end namespace
#endif // RTPTCPSOCKETTRANSMITTER_H

View File

@ -1,333 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
#ifndef RTPHASHTABLE_H
#define RTPHASHTABLE_H
/**
* \file rtphashtable.h
*/
#include "rtperrors.h"
namespace qrtplib
{
//template<class Element,int GetIndex(const Element &k),int hashsize>
template<class Element, class GetIndex, int hashsize>
class RTPHashTable
{
public:
RTPHashTable();
~RTPHashTable()
{
Clear();
}
void GotoFirstElement()
{
curhashelem = firsthashelem;
}
void GotoLastElement()
{
curhashelem = lasthashelem;
}
bool HasCurrentElement()
{
return (curhashelem == 0) ? false : true;
}
int DeleteCurrentElement();
Element &GetCurrentElement()
{
return curhashelem->GetElement();
}
int GotoElement(const Element &e);
bool HasElement(const Element &e);
void GotoNextElement();
void GotoPreviousElement();
void Clear();
int AddElement(const Element &elem);
int DeleteElement(const Element &elem);
private:
class HashElement
{
public:
HashElement(const Element &e, int index) :
element(e)
{
hashprev = 0;
hashnext = 0;
listnext = 0;
listprev = 0;
hashindex = index;
}
int GetHashIndex()
{
return hashindex;
}
Element &GetElement()
{
return element;
}
private:
int hashindex;
Element element;
public:
HashElement *hashprev, *hashnext;
HashElement *listprev, *listnext;
};
HashElement *table[hashsize];
HashElement *firsthashelem, *lasthashelem;
HashElement *curhashelem;
#ifdef RTP_SUPPORT_MEMORYMANAGEMENT
int memorytype;
#endif // RTP_SUPPORT_MEMORYMANAGEMENT
};
template<class Element, class GetIndex, int hashsize>
inline RTPHashTable<Element, GetIndex, hashsize>::RTPHashTable()
{
for (int i = 0; i < hashsize; i++)
table[i] = 0;
firsthashelem = 0;
lasthashelem = 0;
}
template<class Element, class GetIndex, int hashsize>
inline int RTPHashTable<Element, GetIndex, hashsize>::DeleteCurrentElement()
{
if (curhashelem)
{
HashElement *tmp1, *tmp2;
int index;
// First, relink elements in current hash bucket
index = curhashelem->GetHashIndex();
tmp1 = curhashelem->hashprev;
tmp2 = curhashelem->hashnext;
if (tmp1 == 0) // no previous element in hash bucket
{
table[index] = tmp2;
if (tmp2 != 0)
tmp2->hashprev = 0;
}
else // there is a previous element in the hash bucket
{
tmp1->hashnext = tmp2;
if (tmp2 != 0)
tmp2->hashprev = tmp1;
}
// Relink elements in list
tmp1 = curhashelem->listprev;
tmp2 = curhashelem->listnext;
if (tmp1 == 0) // curhashelem is first in list
{
firsthashelem = tmp2;
if (tmp2 != 0)
tmp2->listprev = 0;
else
// curhashelem is also last in list
lasthashelem = 0;
}
else
{
tmp1->listnext = tmp2;
if (tmp2 != 0)
tmp2->listprev = tmp1;
else
// curhashelem is last in list
lasthashelem = tmp1;
}
// finally, with everything being relinked, we can delete curhashelem
delete curhashelem;
curhashelem = tmp2; // Set to next element in the list
}
else
return ERR_RTP_HASHTABLE_NOCURRENTELEMENT;
return 0;
}
template<class Element, class GetIndex, int hashsize>
inline int RTPHashTable<Element, GetIndex, hashsize>::GotoElement(const Element &e)
{
int index;
bool found;
index = GetIndex::GetIndex(e);
if (index >= hashsize)
return ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX;
curhashelem = table[index];
found = false;
while (!found && curhashelem != 0)
{
if (curhashelem->GetElement() == e)
found = true;
else
curhashelem = curhashelem->hashnext;
}
if (!found)
return ERR_RTP_HASHTABLE_ELEMENTNOTFOUND;
return 0;
}
template<class Element, class GetIndex, int hashsize>
inline bool RTPHashTable<Element, GetIndex, hashsize>::HasElement(const Element &e)
{
int index;
bool found;
HashElement *tmp;
index = GetIndex::GetIndex(e);
if (index >= hashsize)
return false;
tmp = table[index];
found = false;
while (!found && tmp != 0)
{
if (tmp->GetElement() == e)
found = true;
else
tmp = tmp->hashnext;
}
return found;
}
template<class Element, class GetIndex, int hashsize>
inline void RTPHashTable<Element, GetIndex, hashsize>::GotoNextElement()
{
if (curhashelem)
curhashelem = curhashelem->listnext;
}
template<class Element, class GetIndex, int hashsize>
inline void RTPHashTable<Element, GetIndex, hashsize>::GotoPreviousElement()
{
if (curhashelem)
curhashelem = curhashelem->listprev;
}
template<class Element, class GetIndex, int hashsize>
inline void RTPHashTable<Element, GetIndex, hashsize>::Clear()
{
HashElement *tmp1, *tmp2;
for (int i = 0; i < hashsize; i++)
table[i] = 0;
tmp1 = firsthashelem;
while (tmp1 != 0)
{
tmp2 = tmp1->listnext;
delete tmp1;
tmp1 = tmp2;
}
firsthashelem = 0;
lasthashelem = 0;
}
template<class Element, class GetIndex, int hashsize>
inline int RTPHashTable<Element, GetIndex, hashsize>::AddElement(const Element &elem)
{
int index;
bool found;
HashElement *e, *newelem;
index = GetIndex::GetIndex(elem);
if (index >= hashsize)
return ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX;
e = table[index];
found = false;
while (!found && e != 0)
{
if (e->GetElement() == elem)
found = true;
else
e = e->hashnext;
}
if (found)
return ERR_RTP_HASHTABLE_ELEMENTALREADYEXISTS;
// Okay, the key doesn't exist, so we can add the new element in the hash table
newelem = new HashElement(elem, index);
if (newelem == 0)
return ERR_RTP_OUTOFMEM;
e = table[index];
table[index] = newelem;
newelem->hashnext = e;
if (e != 0)
e->hashprev = newelem;
// Now, we still got to add it to the linked list
if (firsthashelem == 0)
{
firsthashelem = newelem;
lasthashelem = newelem;
}
else // there already are some elements in the list
{
lasthashelem->listnext = newelem;
newelem->listprev = lasthashelem;
lasthashelem = newelem;
}
return 0;
}
template<class Element, class GetIndex, int hashsize>
inline int RTPHashTable<Element, GetIndex, hashsize>::DeleteElement(const Element &elem)
{
int status;
status = GotoElement(elem);
if (status < 0)
return status;
return DeleteCurrentElement();
}
} // end namespace
#endif // RTPHASHTABLE_H

View File

@ -1,71 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
#include "rtpipv4address.h"
namespace qrtplib
{
bool RTPIPv4Address::IsSameAddress(const RTPAddress *addr) const
{
if (addr == 0)
return false;
if (addr->GetAddressType() != IPv4Address)
return false;
const RTPIPv4Address *addr2 = (const RTPIPv4Address *) addr;
if (addr2->GetIP() == ip && addr2->GetPort() == port)
return true;
return false;
}
bool RTPIPv4Address::IsFromSameHost(const RTPAddress *addr) const
{
if (addr == 0)
return false;
if (addr->GetAddressType() != IPv4Address)
return false;
const RTPIPv4Address *addr2 = (const RTPIPv4Address *) addr;
if (addr2->GetIP() == ip)
return true;
return false;
}
RTPAddress *RTPIPv4Address::CreateCopy() const
{
RTPIPv4Address *a = new RTPIPv4Address(ip, port);
return a;
}
} // end namespace

View File

@ -1,176 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtpipv4address.h
*/
#ifndef RTPIPV4ADDRESS_H
#define RTPIPV4ADDRESS_H
#include "rtpconfig.h"
#include "rtpaddress.h"
#include "rtptypes.h"
#include "util/export.h"
namespace qrtplib
{
/** Represents an IPv4 IP address and port.
* This class is used by the UDP over IPv4 transmission component.
* When an RTPIPv4Address is used in one of the multicast functions of the transmitter, the port
* number is ignored. When an instance is used in one of the accept or ignore functions of the
* transmitter, a zero port number represents all ports for the specified IP address.
*/
class QRTPLIB_API RTPIPv4Address: public RTPAddress
{
public:
/** Creates an instance with IP address \c ip and port number \c port (both
* are interpreted in host byte order), and possibly sets the RTCP multiplex flag
* (see RTPIPv4Address::UseRTCPMultiplexingOnTransmission). */
RTPIPv4Address(uint32_t ip = 0, uint16_t port = 0, bool rtcpmux = false) :
RTPAddress(IPv4Address)
{
RTPIPv4Address::ip = ip;
RTPIPv4Address::port = port;
if (rtcpmux)
rtcpsendport = port;
else
rtcpsendport = port + 1;
}
/** Creates an instance with IP address \c ip and port number \c port (both
* are interpreted in host byte order), and sets a specific port to
* send RTCP packets to (see RTPIPv4Address::GetRTCPSendPort). */
RTPIPv4Address(uint32_t ip, uint16_t port, uint16_t rtcpsendport) :
RTPAddress(IPv4Address)
{
RTPIPv4Address::ip = ip;
RTPIPv4Address::port = port;
RTPIPv4Address::rtcpsendport = rtcpsendport;
}
/** Creates an instance with IP address \c ip and port number \c port (\c port is
* interpreted in host byte order) and possibly sets the RTCP multiplex flag
* (see RTPIPv4Address::UseRTCPMultiplexingOnTransmission). */
RTPIPv4Address(const uint8_t ip[4], uint16_t port = 0, bool rtcpmux = false) :
RTPAddress(IPv4Address)
{
RTPIPv4Address::ip = (uint32_t) ip[3];
RTPIPv4Address::ip |= (((uint32_t) ip[2]) << 8);
RTPIPv4Address::ip |= (((uint32_t) ip[1]) << 16);
RTPIPv4Address::ip |= (((uint32_t) ip[0]) << 24);
RTPIPv4Address::port = port;
if (rtcpmux)
rtcpsendport = port;
else
rtcpsendport = port + 1;
}
/** Creates an instance with IP address \c ip and port number \c port (both
* are interpreted in host byte order), and sets a specific port to
* send RTCP packets to (see RTPIPv4Address::GetRTCPSendPort). */
RTPIPv4Address(const uint8_t ip[4], uint16_t port, uint16_t rtcpsendport) :
RTPAddress(IPv4Address)
{
RTPIPv4Address::ip = (uint32_t) ip[3];
RTPIPv4Address::ip |= (((uint32_t) ip[2]) << 8);
RTPIPv4Address::ip |= (((uint32_t) ip[1]) << 16);
RTPIPv4Address::ip |= (((uint32_t) ip[0]) << 24);
RTPIPv4Address::port = port;
RTPIPv4Address::rtcpsendport = rtcpsendport;
}
~RTPIPv4Address()
{
}
/** Sets the IP address for this instance to \c ip which is assumed to be in host byte order. */
void SetIP(uint32_t ip)
{
RTPIPv4Address::ip = ip;
}
/** Sets the IP address of this instance to \c ip. */
void SetIP(const uint8_t ip[4])
{
RTPIPv4Address::ip = (uint32_t) ip[3];
RTPIPv4Address::ip |= (((uint32_t) ip[2]) << 8);
RTPIPv4Address::ip |= (((uint32_t) ip[1]) << 16);
RTPIPv4Address::ip |= (((uint32_t) ip[0]) << 24);
}
/** Sets the port number for this instance to \c port which is interpreted in host byte order. */
void SetPort(uint16_t port)
{
RTPIPv4Address::port = port;
}
/** Returns the IP address contained in this instance in host byte order. */
uint32_t GetIP() const
{
return ip;
}
/** Returns the port number of this instance in host byte order. */
uint16_t GetPort() const
{
return port;
}
/** For outgoing packets, this indicates to which port RTCP packets will be sent (can,
* be the same port as the RTP packets in case RTCP multiplexing is used). */
uint16_t GetRTCPSendPort() const
{
return rtcpsendport;
}
RTPAddress *CreateCopy() const;
// Note that these functions are only used for received packets, and for those
// the rtcpsendport variable is not important and should be ignored.
bool IsSameAddress(const RTPAddress *addr) const;
bool IsFromSameHost(const RTPAddress *addr) const;
private:
uint32_t ip;
uint16_t port;
uint16_t rtcpsendport;
};
} // end namespace
#endif // RTPIPV4ADDRESS_H

View File

@ -1,50 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2011 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
#include "rtpipv4destination.h"
#include "rtpinternalutils.h"
namespace qrtplib
{
std::string RTPIPv4Destination::GetDestinationString() const
{
char str[24];
uint32_t ip = GetIP();
uint16_t portbase = ntohs(GetRTPPort_NBO());
RTP_SNPRINTF(str, 24, "%d.%d.%d.%d:%d", (int) ((ip >> 24) & 0xFF), (int) ((ip >> 16) & 0xFF), (int) ((ip >> 8) & 0xFF), (int) (ip & 0xFF), (int) (portbase));
return std::string(str);
}
} // end namespace

View File

@ -1,138 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtpipv4destination.h
*/
#ifndef RTPIPV4DESTINATION_H
#define RTPIPV4DESTINATION_H
#include "rtpconfig.h"
#include "rtptypes.h"
#include "rtpipv4address.h"
#ifndef RTP_SOCKETTYPE_WINSOCK
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#endif // RTP_SOCKETTYPE_WINSOCK
#include <string.h>
#include <string>
#include "util/export.h"
namespace qrtplib
{
class QRTPLIB_API RTPIPv4Destination
{
public:
RTPIPv4Destination()
{
ip = 0;
memset(&rtpaddr, 0, sizeof(struct sockaddr_in));
memset(&rtcpaddr, 0, sizeof(struct sockaddr_in));
}
RTPIPv4Destination(uint32_t ip, uint16_t rtpport, uint16_t rtcpport)
{
memset(&rtpaddr, 0, sizeof(struct sockaddr_in));
memset(&rtcpaddr, 0, sizeof(struct sockaddr_in));
rtpaddr.sin_family = AF_INET;
rtpaddr.sin_port = htons(rtpport);
rtpaddr.sin_addr.s_addr = htonl(ip);
rtcpaddr.sin_family = AF_INET;
rtcpaddr.sin_port = htons(rtcpport);
rtcpaddr.sin_addr.s_addr = htonl(ip);
RTPIPv4Destination::ip = ip;
}
bool operator==(const RTPIPv4Destination &src) const
{
if (rtpaddr.sin_addr.s_addr == src.rtpaddr.sin_addr.s_addr && rtpaddr.sin_port == src.rtpaddr.sin_port)
return true;
return false;
}
uint32_t GetIP() const
{
return ip;
}
// nbo = network byte order
uint32_t GetIP_NBO() const
{
return rtpaddr.sin_addr.s_addr;
}
uint16_t GetRTPPort_NBO() const
{
return rtpaddr.sin_port;
}
uint16_t GetRTCPPort_NBO() const
{
return rtcpaddr.sin_port;
}
const struct sockaddr_in *GetRTPSockAddr() const
{
return &rtpaddr;
}
const struct sockaddr_in *GetRTCPSockAddr() const
{
return &rtcpaddr;
}
std::string GetDestinationString() const;
static bool AddressToDestination(const RTPAddress &addr, RTPIPv4Destination &dest)
{
if (addr.GetAddressType() != RTPAddress::IPv4Address)
return false;
const RTPIPv4Address &address = (const RTPIPv4Address &) addr;
uint16_t rtpport = address.GetPort();
uint16_t rtcpport = address.GetRTCPSendPort();
dest = RTPIPv4Destination(address.GetIP(), rtpport, rtcpport);
return true;
}
private:
uint32_t ip;
struct sockaddr_in rtpaddr;
struct sockaddr_in rtcpaddr;
};
} // end namespace
#endif // RTPIPV4DESTINATION_H

View File

@ -1,57 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
#include "rtplibraryversion.h"
#include "rtpdefines.h"
#include "rtplibraryversioninternal.h"
#include "rtpinternalutils.h"
#include <stdio.h>
namespace qrtplib
{
RTPLibraryVersion RTPLibraryVersion::GetVersion()
{
return RTPLibraryVersion(JRTPLIB_VERSION_MAJOR, JRTPLIB_VERSION_MINOR, JRTPLIB_VERSION_DEBUG);
}
std::string RTPLibraryVersion::GetVersionString() const
{
char str[16];
RTP_SNPRINTF(str, 16, "%d.%d.%d", majornr, minornr, debugnr);
return std::string(str);
}
} // end namespace

View File

@ -1,93 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtplibraryversion.h
*/
#ifndef RTPLIBRARYVERSION_H
#define RTPLIBRARYVERSION_H
#include "rtpconfig.h"
#include <string>
#include <stdio.h>
#include "util/export.h"
namespace qrtplib
{
/**
* Used to provide information about the version of the library.
*/
class QRTPLIB_API RTPLibraryVersion
{
public:
/** Returns an instance of RTPLibraryVersion describing the version of the library. */
static RTPLibraryVersion GetVersion();
private:
RTPLibraryVersion(int major, int minor, int debug)
{
majornr = major;
minornr = minor;
debugnr = debug;
}
public:
/** Returns the major version number. */
int GetMajorNumber() const
{
return majornr;
}
/** Returns the minor version number. */
int GetMinorNumber() const
{
return minornr;
}
/** Returns the debug version number. */
int GetDebugNumber() const
{
return debugnr;
}
/** Returns a string describing the library version. */
std::string GetVersionString() const;
private:
int debugnr, minornr, majornr;
};
} // end namespace
#endif // RTPLIBRARYVERSION_H

View File

@ -1,190 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtpselect.h
*/
#ifndef RTPSELECT_H
#define RTPSELECT_H
#include "rtpconfig.h"
#include "rtptypes.h"
#include "rtperrors.h"
#include "rtptimeutilities.h"
#include "rtpsocketutil.h"
#if defined(RTP_HAVE_WSAPOLL) || defined(RTP_HAVE_POLL)
#ifndef RTP_HAVE_WSAPOLL
#include <poll.h>
#include <errno.h>
#endif // !RTP_HAVE_WSAPOLL
#include <vector>
#include <limits>
namespace qrtplib
{
inline int RTPSelect(const SocketType *sockets, int8_t *readflags, std::size_t numsocks, RTPTime timeout)
{
using namespace std;
vector<struct pollfd> fds(numsocks);
for (std::size_t i = 0; i < numsocks; i++)
{
fds[i].fd = sockets[i];
fds[i].events = POLLIN;
fds[i].revents = 0;
readflags[i] = 0;
}
int timeoutmsec = -1;
if (timeout.GetDouble() >= 0)
{
double dtimeoutmsec = timeout.GetDouble() * 1000.0;
if (dtimeoutmsec > (numeric_limits<int>::max)()) // parentheses to prevent windows 'max' macro expansion
dtimeoutmsec = (numeric_limits<int>::max)();
timeoutmsec = (int) dtimeoutmsec;
}
#ifdef RTP_HAVE_WSAPOLL
int status = WSAPoll(&(fds[0]), (ULONG)numsocks, timeoutmsec);
if (status < 0)
return ERR_RTP_SELECT_ERRORINPOLL;
#else
int status = poll(&(fds[0]), numsocks, timeoutmsec);
if (status < 0)
{
// We're just going to ignore an EINTR
if (errno == EINTR)
return 0;
return ERR_RTP_SELECT_ERRORINPOLL;
}
#endif // RTP_HAVE_WSAPOLL
if (status > 0)
{
for (std::size_t i = 0; i < numsocks; i++)
{
if (fds[i].revents)
readflags[i] = 1;
}
}
return status;
}
} // end namespace
#else
#ifndef RTP_SOCKETTYPE_WINSOCK
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#endif // !RTP_SOCKETTYPE_WINSOCK
namespace qrtplib
{
/** Wrapper function around 'select', 'poll' or 'WSAPoll', depending on the
* availability on your platform.
*
* Wrapper function around 'select', 'poll' or 'WSAPoll', depending on the
* availability on your platform. The function will check the specified
* `sockets` for incoming data and sets the flags in `readflags` if so.
* A maximum time `timeout` will be waited for data to arrive, which is
* indefinitely if set to a negative value. The function returns the number
* of sockets that have data incoming.
*/
inline int RTPSelect(const SocketType *sockets, int8_t *readflags, std::size_t numsocks, RTPTime timeout)
{
struct timeval tv;
struct timeval *pTv = 0;
if (timeout.GetDouble() >= 0)
{
tv.tv_sec = (long)timeout.GetSeconds();
tv.tv_usec = timeout.GetMicroSeconds();
pTv = &tv;
}
fd_set fdset;
FD_ZERO(&fdset);
for (std::size_t i = 0; i < numsocks; i++)
{
#ifndef RTP_SOCKETTYPE_WINSOCK
const int setsize = FD_SETSIZE;
// On windows it seems that comparing the socket value to FD_SETSIZE does
// not make sense
if (sockets[i] >= setsize)
return ERR_RTP_SELECT_SOCKETDESCRIPTORTOOLARGE;
#endif // RTP_SOCKETTYPE_WINSOCK
FD_SET(sockets[i], &fdset);
readflags[i] = 0;
}
int status = select(FD_SETSIZE, &fdset, 0, 0, pTv);
#ifdef RTP_SOCKETTYPE_WINSOCK
if (status < 0)
return ERR_RTP_SELECT_ERRORINSELECT;
#else
if (status < 0)
{
// We're just going to ignore an EINTR
if (errno == EINTR)
return 0;
return ERR_RTP_SELECT_ERRORINSELECT;
}
#endif // RTP_HAVE_WSAPOLL
if (status > 0) // some descriptors were set, check them
{
for (std::size_t i = 0; i < numsocks; i++)
{
if (FD_ISSET(sockets[i], &fdset))
readflags[i] = 1;
}
}
return status;
}
} // end namespace
#endif // RTP_HAVE_POLL || RTP_HAVE_WSAPOLL
#endif // RTPSELECT_H

View File

@ -39,7 +39,6 @@
#define RTPSESSION_H
#include "rtpconfig.h"
#include "rtplibraryversion.h"
#include "rtppacketbuilder.h"
#include "rtpsessionsources.h"
#include "rtptransmitter.h"

View File

@ -1,66 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
#include "rtptcpaddress.h"
namespace qrtplib
{
bool RTPTCPAddress::IsSameAddress(const RTPAddress *addr) const
{
if (addr == 0)
return false;
if (addr->GetAddressType() != TCPAddress)
return false;
const RTPTCPAddress *a = static_cast<const RTPTCPAddress *>(addr);
// We're using a socket to identify connections
if (a->m_socket == m_socket)
return true;
return false;
}
bool RTPTCPAddress::IsFromSameHost(const RTPAddress *addr) const
{
return IsSameAddress(addr);
}
RTPAddress *RTPTCPAddress::CreateCopy() const
{
RTPTCPAddress *a = new RTPTCPAddress(m_socket);
return a;
}
} // end namespace

View File

@ -1,89 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtptcpaddress.h
*/
#ifndef RTPTCPADDRESS_H
#define RTPTCPADDRESS_H
#include "rtpconfig.h"
#include "rtpaddress.h"
#include "rtptypes.h"
#include "rtpsocketutil.h"
#include "util/export.h"
namespace qrtplib
{
/** Represents a TCP 'address' and port.
* This class is used by the TCP transmission component, to specify which sockets
* should be used to send/receive data, and to know on which socket incoming data
* was received.
*/
class QRTPLIB_API RTPTCPAddress: public RTPAddress
{
public:
/** Creates an instance with which you can use a specific socket
* in the TCP transmitter (must be connected). */
RTPTCPAddress(SocketType sock) :
RTPAddress(TCPAddress)
{
m_socket = sock;
}
~RTPTCPAddress()
{
}
/** Returns the socket that was specified in the constructor. */
SocketType GetSocket() const
{
return m_socket;
}
RTPAddress *CreateCopy() const;
// Note that these functions are only used for received packets
bool IsSameAddress(const RTPAddress *addr) const;
bool IsFromSameHost(const RTPAddress *addr) const;
private:
SocketType m_socket;
};
} // end namespace
#endif // RTPTCPADDRESS_H

View File

@ -1,831 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
#include "rtptcptransmitter.h"
#include "rtprawpacket.h"
#include "rtptcpaddress.h"
#include "rtptimeutilities.h"
#include "rtpdefines.h"
#include "rtpstructs.h"
#include "rtpsocketutilinternal.h"
#include "rtpinternalutils.h"
#include "rtpselect.h"
#include <stdio.h>
#include <assert.h>
#include <vector>
#include <iostream>
using namespace std;
#define RTPTCPTRANS_MAXPACKSIZE 65535
namespace qrtplib
{
RTPTCPTransmitter::RTPTCPTransmitter()
{
m_created = false;
m_init = false;
}
RTPTCPTransmitter::~RTPTCPTransmitter()
{
Destroy();
}
int RTPTCPTransmitter::Init(bool tsafe)
{
if (m_init)
return ERR_RTP_TCPTRANS_ALREADYINIT;
if (tsafe)
return ERR_RTP_NOTHREADSUPPORT;
m_maxPackSize = RTPTCPTRANS_MAXPACKSIZE;
m_init = true;
return 0;
}
int RTPTCPTransmitter::Create(std::size_t maximumpacketsize __attribute__((unused)), const RTPTransmissionParams *transparams)
{
const RTPTCPTransmissionParams *params, defaultparams;
int status;
if (!m_init)
return ERR_RTP_TCPTRANS_NOTINIT;
if (m_created)
{
return ERR_RTP_TCPTRANS_ALREADYCREATED;
}
// Obtain transmission parameters
if (transparams == 0)
params = &defaultparams;
else
{
if (transparams->GetTransmissionProtocol() != RTPTransmitter::TCPProto)
{
return ERR_RTP_TCPTRANS_ILLEGALPARAMETERS;
}
params = static_cast<const RTPTCPTransmissionParams *>(transparams);
}
if (!params->GetCreatedAbortDescriptors())
{
if ((status = m_abortDesc.Init()) < 0)
{
return status;
}
m_pAbortDesc = &m_abortDesc;
}
else
{
m_pAbortDesc = params->GetCreatedAbortDescriptors();
if (!m_pAbortDesc->IsInitialized())
{
return ERR_RTP_ABORTDESC_NOTINIT;
}
}
m_waitingForData = false;
m_created = true;
return 0;
}
void RTPTCPTransmitter::Destroy()
{
if (!m_init)
return;
if (!m_created)
{
return;
}
ClearDestSockets();
FlushPackets();
m_created = false;
if (m_waitingForData)
{
m_pAbortDesc->SendAbortSignal();
m_abortDesc.Destroy(); // Doesn't do anything if not initialized
// to make sure that the WaitForIncomingData function ended
}
else
m_abortDesc.Destroy(); // Doesn't do anything if not initialized
}
RTPTransmissionInfo *RTPTCPTransmitter::GetTransmissionInfo()
{
if (!m_init)
return 0;
RTPTransmissionInfo *tinf = new RTPTCPTransmissionInfo();
return tinf;
}
void RTPTCPTransmitter::DeleteTransmissionInfo(RTPTransmissionInfo *i)
{
if (!m_init)
return;
delete i;
}
int RTPTCPTransmitter::GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength)
{
if (!m_init)
return ERR_RTP_TCPTRANS_NOTINIT;
if (!m_created)
{
return ERR_RTP_TCPTRANS_NOTCREATED;
}
if (m_localHostname.size() == 0)
{
//
// TODO
// TODO
// TODO
// TODO
//
m_localHostname.resize(9);
memcpy(&m_localHostname[0], "localhost", m_localHostname.size());
}
if ((*bufferlength) < m_localHostname.size())
{
*bufferlength = m_localHostname.size(); // tell the application the required size of the buffer
return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL;
}
memcpy(buffer, &m_localHostname[0], m_localHostname.size());
*bufferlength = m_localHostname.size();
return 0;
}
bool RTPTCPTransmitter::ComesFromThisTransmitter(const RTPAddress *addr)
{
if (!m_init)
return false;
if (addr == 0)
return false;
if (!m_created)
return false;
if (addr->GetAddressType() != RTPAddress::TCPAddress)
return false;
bool v = false;
// TODO: for now, we're assuming that we can't just send to the same transmitter
return v;
}
int RTPTCPTransmitter::Poll()
{
if (!m_init)
return ERR_RTP_TCPTRANS_NOTINIT;
if (!m_created)
{
return ERR_RTP_TCPTRANS_NOTCREATED;
}
std::map<SocketType, SocketData>::iterator it = m_destSockets.begin();
std::map<SocketType, SocketData>::iterator end = m_destSockets.end();
int status = 0;
vector<SocketType> errSockets;
while (it != end)
{
SocketType sock = it->first;
status = PollSocket(sock, it->second);
if (status < 0)
{
// Stop immediately on out of memory
if (status == ERR_RTP_OUTOFMEM)
break;
else
{
errSockets.push_back(sock);
// Don't let this count as an error (due to a closed connection for example),
// otherwise the poll thread (if used) will stop because of this. Since there
// may be more than one connection, that's not desirable in general.
status = 0;
}
}
++it;
}
for (std::size_t i = 0; i < errSockets.size(); i++)
OnReceiveError(errSockets[i]);
return status;
}
int RTPTCPTransmitter::WaitForIncomingData(const RTPTime &delay, bool *dataavailable)
{
if (!m_init)
return ERR_RTP_TCPTRANS_NOTINIT;
if (!m_created)
{
return ERR_RTP_TCPTRANS_NOTCREATED;
}
if (m_waitingForData)
{
return ERR_RTP_TCPTRANS_ALREADYWAITING;
}
m_tmpSocks.resize(m_destSockets.size() + 1);
m_tmpFlags.resize(m_tmpSocks.size());
SocketType abortSocket = m_pAbortDesc->GetAbortSocket();
std::map<SocketType, SocketData>::iterator it = m_destSockets.begin();
std::map<SocketType, SocketData>::iterator end = m_destSockets.end();
int idx = 0;
while (it != end)
{
m_tmpSocks[idx] = it->first;
m_tmpFlags[idx] = 0;
++it;
idx++;
}
m_tmpSocks[idx] = abortSocket;
m_tmpFlags[idx] = 0;
int idxAbort = idx;
m_waitingForData = true;
//cout << "Waiting for " << delay.GetDouble() << " seconds for data on " << m_tmpSocks.size() << " sockets" << endl;
int status = RTPSelect(&m_tmpSocks[0], &m_tmpFlags[0], m_tmpSocks.size(), delay);
if (status < 0)
{
m_waitingForData = false;
return status;
}
m_waitingForData = false;
if (!m_created) // destroy called
{
return 0;
}
// if aborted, read from abort buffer
if (m_tmpFlags[idxAbort])
m_pAbortDesc->ReadSignallingByte();
if (dataavailable != 0)
{
bool avail = false;
for (std::size_t i = 0; i < m_tmpFlags.size(); i++)
{
if (m_tmpFlags[i])
{
avail = true;
//cout << "Data available!" << endl;
break;
}
}
if (avail)
*dataavailable = true;
else
*dataavailable = false;
}
return 0;
}
int RTPTCPTransmitter::AbortWait()
{
if (!m_init)
return ERR_RTP_TCPTRANS_NOTINIT;
if (!m_created)
{
return ERR_RTP_TCPTRANS_NOTCREATED;
}
if (!m_waitingForData)
{
return ERR_RTP_TCPTRANS_NOTWAITING;
}
m_pAbortDesc->SendAbortSignal();
return 0;
}
int RTPTCPTransmitter::SendRTPData(const void *data, std::size_t len)
{
return SendRTPRTCPData(data, len);
}
int RTPTCPTransmitter::SendRTCPData(const void *data, std::size_t len)
{
return SendRTPRTCPData(data, len);
}
int RTPTCPTransmitter::AddDestination(const RTPAddress &addr)
{
if (!m_init)
return ERR_RTP_TCPTRANS_NOTINIT;
if (!m_created)
{
return ERR_RTP_TCPTRANS_NOTCREATED;
}
if (addr.GetAddressType() != RTPAddress::TCPAddress)
{
return ERR_RTP_TCPTRANS_INVALIDADDRESSTYPE;
}
const RTPTCPAddress &a = static_cast<const RTPTCPAddress &>(addr);
SocketType s = a.GetSocket();
if (s == 0)
{
return ERR_RTP_TCPTRANS_NOSOCKETSPECIFIED;
}
int status = ValidateSocket(s);
if (status != 0)
{
return status;
}
std::map<SocketType, SocketData>::iterator it = m_destSockets.find(s);
if (it != m_destSockets.end())
{
return ERR_RTP_TCPTRANS_SOCKETALREADYINDESTINATIONS;
}
m_destSockets[s] = SocketData();
// Because the sockets are also used for incoming data, we'll abort a wait
// that may be in progress, otherwise it could take a few seconds until the
// new socket is monitored for incoming data
m_pAbortDesc->SendAbortSignal();
return 0;
}
int RTPTCPTransmitter::DeleteDestination(const RTPAddress &addr)
{
if (!m_init)
return ERR_RTP_TCPTRANS_NOTINIT;
if (!m_created)
{
return ERR_RTP_TCPTRANS_NOTCREATED;
}
if (addr.GetAddressType() != RTPAddress::TCPAddress)
{
return ERR_RTP_TCPTRANS_INVALIDADDRESSTYPE;
}
const RTPTCPAddress &a = static_cast<const RTPTCPAddress &>(addr);
SocketType s = a.GetSocket();
if (s == 0)
{
return ERR_RTP_TCPTRANS_NOSOCKETSPECIFIED;
}
std::map<SocketType, SocketData>::iterator it = m_destSockets.find(s);
if (it == m_destSockets.end())
{
return ERR_RTP_TCPTRANS_SOCKETNOTFOUNDINDESTINATIONS;
}
// Clean up possibly allocated memory
uint8_t *pBuf = it->second.ExtractDataBuffer();
if (pBuf)
delete[] pBuf;
m_destSockets.erase(it);
return 0;
}
void RTPTCPTransmitter::ClearDestinations()
{
if (!m_init)
return;
if (m_created)
ClearDestSockets();
}
bool RTPTCPTransmitter::SupportsMulticasting()
{
return false;
}
int RTPTCPTransmitter::JoinMulticastGroup(const RTPAddress &)
{
return ERR_RTP_TCPTRANS_NOMULTICASTSUPPORT;
}
int RTPTCPTransmitter::LeaveMulticastGroup(const RTPAddress &)
{
return ERR_RTP_TCPTRANS_NOMULTICASTSUPPORT;
}
void RTPTCPTransmitter::LeaveAllMulticastGroups()
{
}
int RTPTCPTransmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m)
{
if (m != RTPTransmitter::AcceptAll)
return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED;
return 0;
}
int RTPTCPTransmitter::AddToIgnoreList(const RTPAddress &)
{
return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED;
}
int RTPTCPTransmitter::DeleteFromIgnoreList(const RTPAddress &)
{
return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED;
}
void RTPTCPTransmitter::ClearIgnoreList()
{
}
int RTPTCPTransmitter::AddToAcceptList(const RTPAddress &)
{
return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED;
}
int RTPTCPTransmitter::DeleteFromAcceptList(const RTPAddress &)
{
return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED;
}
void RTPTCPTransmitter::ClearAcceptList()
{
}
int RTPTCPTransmitter::SetMaximumPacketSize(std::size_t s)
{
if (!m_init)
return ERR_RTP_TCPTRANS_NOTINIT;
if (!m_created)
{
return ERR_RTP_TCPTRANS_NOTCREATED;
}
if (s > RTPTCPTRANS_MAXPACKSIZE)
{
return ERR_RTP_TCPTRANS_SPECIFIEDSIZETOOBIG;
}
m_maxPackSize = s;
return 0;
}
bool RTPTCPTransmitter::NewDataAvailable()
{
if (!m_init)
return false;
bool v;
if (!m_created)
v = false;
else
{
if (m_rawpacketlist.empty())
v = false;
else
v = true;
}
return v;
}
RTPRawPacket *RTPTCPTransmitter::GetNextPacket()
{
if (!m_init)
return 0;
RTPRawPacket *p;
if (!m_created)
{
return 0;
}
if (m_rawpacketlist.empty())
{
return 0;
}
p = *(m_rawpacketlist.begin());
m_rawpacketlist.pop_front();
return p;
}
// Here the private functions start...
void RTPTCPTransmitter::FlushPackets()
{
std::list<RTPRawPacket*>::const_iterator it;
for (it = m_rawpacketlist.begin(); it != m_rawpacketlist.end(); ++it)
delete *it;
m_rawpacketlist.clear();
}
int RTPTCPTransmitter::PollSocket(SocketType sock, SocketData &sdata)
{
#ifdef RTP_SOCKETTYPE_WINSOCK
unsigned long len;
#else
std::size_t len;
#endif // RTP_SOCKETTYPE_WINSOCK
bool dataavailable;
do
{
len = 0;
RTPIOCTL(sock, FIONREAD, &len);
if (len <= 0)
dataavailable = false;
else
dataavailable = true;
if (dataavailable)
{
RTPTime curtime = RTPTime::CurrentTime();
int relevantLen = RTPTCPTRANS_MAXPACKSIZE + 2;
if ((int) len < relevantLen)
relevantLen = (int) len;
bool complete = false;
int status = sdata.ProcessAvailableBytes(sock, relevantLen, complete);
if (status < 0)
return status;
if (complete)
{
uint8_t *pBuf = sdata.ExtractDataBuffer();
if (pBuf)
{
int dataLength = sdata.m_dataLength;
sdata.Reset();
RTPTCPAddress *pAddr = new RTPTCPAddress(sock);
if (pAddr == 0)
return ERR_RTP_OUTOFMEM;
bool isrtp = true;
if (dataLength > (int) sizeof(RTCPCommonHeader))
{
RTCPCommonHeader *rtcpheader = (RTCPCommonHeader *) pBuf;
uint8_t packettype = rtcpheader->packettype;
if (packettype >= 200 && packettype <= 204)
isrtp = false;
}
RTPRawPacket *pPack = new RTPRawPacket(pBuf, dataLength, pAddr, curtime, isrtp);
if (pPack == 0)
{
delete pAddr;
delete[] pBuf;
return ERR_RTP_OUTOFMEM;
}
m_rawpacketlist.push_back(pPack);
}
}
}
} while (dataavailable);
return 0;
}
int RTPTCPTransmitter::SendRTPRTCPData(const void *data, std::size_t len)
{
if (!m_init)
return ERR_RTP_TCPTRANS_NOTINIT;
if (!m_created)
{
return ERR_RTP_TCPTRANS_NOTCREATED;
}
if (len > RTPTCPTRANS_MAXPACKSIZE)
{
return ERR_RTP_TCPTRANS_SPECIFIEDSIZETOOBIG;
}
std::map<SocketType, SocketData>::iterator it = m_destSockets.begin();
std::map<SocketType, SocketData>::iterator end = m_destSockets.end();
vector<SocketType> errSockets;
int flags = 0;
#ifdef RTP_HAVE_MSG_NOSIGNAL
flags = MSG_NOSIGNAL;
#endif // RTP_HAVE_MSG_NOSIGNAL
while (it != end)
{
uint8_t lengthBytes[2] =
{ (uint8_t) ((len >> 8) & 0xff), (uint8_t) (len & 0xff) };
SocketType sock = it->first;
if (send(sock, (const char *) lengthBytes, 2, flags) < 0 || send(sock, (const char *) data, len, flags) < 0)
errSockets.push_back(sock);
++it;
}
if (errSockets.size() != 0)
{
for (std::size_t i = 0; i < errSockets.size(); i++)
OnSendError(errSockets[i]);
}
// Don't return an error code to avoid the poll thread exiting
// due to one closed connection for example
return 0;
}
int RTPTCPTransmitter::ValidateSocket(SocketType)
{
// TODO: should we even do a check (for a TCP socket)?
return 0;
}
void RTPTCPTransmitter::ClearDestSockets()
{
std::map<SocketType, SocketData>::iterator it = m_destSockets.begin();
std::map<SocketType, SocketData>::iterator end = m_destSockets.end();
while (it != end)
{
uint8_t *pBuf = it->second.ExtractDataBuffer();
if (pBuf)
delete[] pBuf;
++it;
}
m_destSockets.clear();
}
RTPTCPTransmitter::SocketData::SocketData()
{
Reset();
}
void RTPTCPTransmitter::SocketData::Reset()
{
m_lengthBufferOffset = 0;
m_dataLength = 0;
m_dataBufferOffset = 0;
m_pDataBuffer = 0;
}
RTPTCPTransmitter::SocketData::~SocketData()
{
assert(m_pDataBuffer == 0); // Should be deleted externally to avoid storing a memory manager in the class
}
int RTPTCPTransmitter::SocketData::ProcessAvailableBytes(SocketType sock, int availLen, bool &complete)
{
const int numLengthBuffer = 2;
if (m_lengthBufferOffset < numLengthBuffer) // first we need to get the length
{
assert(m_pDataBuffer == 0);
int num = numLengthBuffer - m_lengthBufferOffset;
if (num > availLen)
num = availLen;
int r = 0;
if (num > 0)
{
r = (int) recv(sock, (char *) (m_lengthBuffer + m_lengthBufferOffset), num, 0);
if (r < 0)
return ERR_RTP_TCPTRANS_ERRORINRECV;
}
m_lengthBufferOffset += r;
availLen -= r;
assert(m_lengthBufferOffset <= numLengthBuffer);
if (m_lengthBufferOffset == numLengthBuffer) // we can constuct a length
{
int l = 0;
for (int i = numLengthBuffer - 1, shift = 0; i >= 0; i--, shift += 8)
l |= ((int) m_lengthBuffer[i]) << shift;
m_dataLength = l;
m_dataBufferOffset = 0;
//cout << "Expecting " << m_dataLength << " bytes" << endl;
// avoid allocation of length 0
if (l == 0)
l = 1;
// We don't yet know if it's an RTP or RTCP packet, so we'll stick to RTP
m_pDataBuffer = new uint8_t[l];
if (m_pDataBuffer == 0)
return ERR_RTP_OUTOFMEM;
}
}
if (m_lengthBufferOffset == numLengthBuffer && m_pDataBuffer) // the last one is to make sure we didn't run out of memory
{
if (m_dataBufferOffset < m_dataLength)
{
int num = m_dataLength - m_dataBufferOffset;
if (num > availLen)
num = availLen;
int r = 0;
if (num > 0)
{
r = (int) recv(sock, (char *) (m_pDataBuffer + m_dataBufferOffset), num, 0);
if (r < 0)
return ERR_RTP_TCPTRANS_ERRORINRECV;
}
m_dataBufferOffset += r;
availLen -= r;
}
if (m_dataBufferOffset == m_dataLength)
complete = true;
}
return 0;
}
} // end namespace

View File

@ -1,229 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtptcptransmitter.h
*/
#ifndef RTPTCPTRANSMITTER_H
#define RTPTCPTRANSMITTER_H
#include "rtpconfig.h"
#include "rtptransmitter.h"
#include "rtpsocketutil.h"
#include "rtpabortdescriptors.h"
#include <map>
#include <list>
#include <vector>
#include "util/export.h"
namespace qrtplib
{
/** Parameters for the TCP transmitter. */
class QRTPLIB_API RTPTCPTransmissionParams: public RTPTransmissionParams
{
public:
RTPTCPTransmissionParams();
/** If non null, the specified abort descriptors will be used to cancel
* the function that's waiting for packets to arrive; set to null (the default)
* to let the transmitter create its own instance. */
void SetCreatedAbortDescriptors(RTPAbortDescriptors *desc)
{
m_pAbortDesc = desc;
}
/** If non-null, this RTPAbortDescriptors instance will be used internally,
* which can be useful when creating your own poll thread for multiple
* sessions. */
RTPAbortDescriptors *GetCreatedAbortDescriptors() const
{
return m_pAbortDesc;
}
private:
RTPAbortDescriptors *m_pAbortDesc;
};
inline RTPTCPTransmissionParams::RTPTCPTransmissionParams() :
RTPTransmissionParams(RTPTransmitter::TCPProto)
{
m_pAbortDesc = 0;
}
/** Additional information about the TCP transmitter. */
class RTPTCPTransmissionInfo: public RTPTransmissionInfo
{
public:
RTPTCPTransmissionInfo() :
RTPTransmissionInfo(RTPTransmitter::TCPProto)
{
}
~RTPTCPTransmissionInfo()
{
}
};
// TODO: this is for IPv4, and will only be valid if one rtp packet is in one tcp frame
#define RTPTCPTRANS_HEADERSIZE (20+20+2) // 20 IP, 20 TCP, 2 for framing (RFC 4571)
/** A TCP transmission component.
*
* This class inherits the RTPTransmitter interface and implements a transmission component
* which uses TCP to send and receive RTP and RTCP data. The component's parameters
* are described by the class RTPTCPTransmissionParams. The functions which have an RTPAddress
* argument require an argument of RTPTCPAddress. The RTPTransmitter::GetTransmissionInfo member function
* returns an instance of type RTPTCPTransmissionInfo.
*
* After this transmission component was created, no data will actually be sent or received
* yet. You can specify over which TCP connections (which must be established first) data
* should be transmitted by using the RTPTransmitter::AddDestination member function. This
* takes an argument of type RTPTCPAddress, with which relevant the socket descriptor can
* be passed to the transmitter.
*
* These sockets will also be used to check for incoming RTP or RTCP data. The RTPTCPAddress
* instance that's associated with a received packet, will contain the socket descriptor
* on which the data was received. This descriptor can be obtained using RTPTCPAddress::GetSocket.
*
* To get notified of an error when sending over or receiving from a socket, override the
* RTPTCPTransmitter::OnSendError and RTPTCPTransmitter::OnReceiveError member functions.
*/
class RTPTCPTransmitter : public RTPTransmitter
{
public:
RTPTCPTransmitter();
~RTPTCPTransmitter();
int Init(bool treadsafe);
int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams);
void Destroy();
RTPTransmissionInfo *GetTransmissionInfo();
void DeleteTransmissionInfo(RTPTransmissionInfo *inf);
int GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength);
bool ComesFromThisTransmitter(const RTPAddress *addr);
std::size_t GetHeaderOverhead()
{
return RTPTCPTRANS_HEADERSIZE;
}
int Poll();
int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0);
int AbortWait();
int SendRTPData(const void *data, std::size_t len);
int SendRTCPData(const void *data, std::size_t len);
int AddDestination(const RTPAddress &addr);
int DeleteDestination(const RTPAddress &addr);
void ClearDestinations();
bool SupportsMulticasting();
int JoinMulticastGroup(const RTPAddress &addr);
int LeaveMulticastGroup(const RTPAddress &addr);
void LeaveAllMulticastGroups();
int SetReceiveMode(RTPTransmitter::ReceiveMode m);
int AddToIgnoreList(const RTPAddress &addr);
int DeleteFromIgnoreList(const RTPAddress &addr);
void ClearIgnoreList();
int AddToAcceptList(const RTPAddress &addr);
int DeleteFromAcceptList(const RTPAddress &addr);
void ClearAcceptList();
int SetMaximumPacketSize(std::size_t s);
bool NewDataAvailable();
RTPRawPacket *GetNextPacket();
protected:
/** By overriding this function you can be notified of an error when sending over a socket. */
virtual void OnSendError(SocketType sock);
/** By overriding this function you can be notified of an error when receiving from a socket. */
virtual void OnReceiveError(SocketType sock);
private:
class SocketData
{
public:
SocketData();
~SocketData();
void Reset();
uint8_t m_lengthBuffer[2];
int m_lengthBufferOffset;
int m_dataLength;
int m_dataBufferOffset;
uint8_t *m_pDataBuffer;
uint8_t *ExtractDataBuffer()
{
uint8_t *pTmp = m_pDataBuffer;
m_pDataBuffer = 0;
return pTmp;
}
int ProcessAvailableBytes(SocketType sock, int availLen, bool &complete);
};
int SendRTPRTCPData(const void *data, std::size_t len);
void FlushPackets();
int PollSocket(SocketType sock, SocketData &sdata);
void ClearDestSockets();
int ValidateSocket(SocketType s);
bool m_init;
bool m_created;
bool m_waitingForData;
std::map<SocketType, SocketData> m_destSockets;
std::vector<SocketType> m_tmpSocks;
std::vector<int8_t> m_tmpFlags;
std::vector<uint8_t> m_localHostname;
std::size_t m_maxPackSize;
std::list<RTPRawPacket*> m_rawpacketlist;
RTPAbortDescriptors m_abortDesc;
RTPAbortDescriptors *m_pAbortDesc; // in case an external one was specified
};
inline void RTPTCPTransmitter::OnSendError(SocketType)
{
}
inline void RTPTCPTransmitter::OnReceiveError(SocketType)
{
}
} // end namespace
#endif // RTPTCPTRANSMITTER_H

File diff suppressed because it is too large Load Diff

View File

@ -1,488 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtpudpv4transmitter.h
*/
#ifndef RTPUDPV4TRANSMITTER_H
#define RTPUDPV4TRANSMITTER_H
#include "rtpconfig.h"
#include "rtptransmitter.h"
#include "rtpipv4destination.h"
#include "rtphashtable.h"
#include "rtpkeyhashtable.h"
#include "rtpsocketutil.h"
#include "rtpabortdescriptors.h"
#include <list>
#include "util/export.h"
#define RTPUDPV4TRANS_HASHSIZE 8317
#define RTPUDPV4TRANS_DEFAULTPORTBASE 5000
#define RTPUDPV4TRANS_RTPRECEIVEBUFFER 32768
#define RTPUDPV4TRANS_RTCPRECEIVEBUFFER 32768
#define RTPUDPV4TRANS_RTPTRANSMITBUFFER 32768
#define RTPUDPV4TRANS_RTCPTRANSMITBUFFER 32768
namespace qrtplib
{
/** Parameters for the UDP over IPv4 transmitter. */
class QRTPLIB_API RTPUDPv4TransmissionParams: public RTPTransmissionParams
{
public:
RTPUDPv4TransmissionParams();
/** Sets the IP address which is used to bind the sockets to \c ip. */
void SetBindIP(uint32_t ip)
{
bindIP = ip;
}
/** Sets the multicast interface IP address. */
void SetMulticastInterfaceIP(uint32_t ip)
{
mcastifaceIP = ip;
}
/** Sets the RTP portbase to \c pbase, which has to be an even number
* unless RTPUDPv4TransmissionParams::SetAllowOddPortbase was called;
* a port number of zero will cause a port to be chosen automatically. */
void SetPortbase(uint16_t pbase)
{
portbase = pbase;
}
/** Sets the multicast TTL to be used to \c mcastTTL. */
void SetMulticastTTL(uint8_t mcastTTL)
{
multicastTTL = mcastTTL;
}
/** Passes a list of IP addresses which will be used as the local IP addresses. */
void SetLocalIPList(std::list<uint32_t> &iplist)
{
localIPs = iplist;
}
/** Clears the list of local IP addresses.
* Clears the list of local IP addresses. An empty list will make the transmission
* component itself determine the local IP addresses.
*/
void ClearLocalIPList()
{
localIPs.clear();
}
/** Returns the IP address which will be used to bind the sockets. */
uint32_t GetBindIP() const
{
return bindIP;
}
/** Returns the multicast interface IP address. */
uint32_t GetMulticastInterfaceIP() const
{
return mcastifaceIP;
}
/** Returns the RTP portbase which will be used (default is 5000). */
uint16_t GetPortbase() const
{
return portbase;
}
/** Returns the multicast TTL which will be used (default is 1). */
uint8_t GetMulticastTTL() const
{
return multicastTTL;
}
/** Returns the list of local IP addresses. */
const std::list<uint32_t> &GetLocalIPList() const
{
return localIPs;
}
/** Sets the RTP socket's send buffer size. */
void SetRTPSendBuffer(int s)
{
rtpsendbuf = s;
}
/** Sets the RTP socket's receive buffer size. */
void SetRTPReceiveBuffer(int s)
{
rtprecvbuf = s;
}
/** Sets the RTCP socket's send buffer size. */
void SetRTCPSendBuffer(int s)
{
rtcpsendbuf = s;
}
/** Sets the RTCP socket's receive buffer size. */
void SetRTCPReceiveBuffer(int s)
{
rtcprecvbuf = s;
}
/** Enables or disables multiplexing RTCP traffic over the RTP channel, so that only a single port is used. */
void SetRTCPMultiplexing(bool f)
{
rtcpmux = f;
}
/** Can be used to allow the RTP port base to be any number, not just even numbers. */
void SetAllowOddPortbase(bool f)
{
allowoddportbase = f;
}
/** Force the RTCP socket to use a specific port, not necessarily one more than
* the RTP port (set this to zero to disable). */
void SetForcedRTCPPort(uint16_t rtcpport)
{
forcedrtcpport = rtcpport;
}
/** Use sockets that have already been created, no checks on port numbers
* will be done, and no buffer sizes will be set; you'll need to close
* the sockets yourself when done, it will **not** be done automatically. */
void SetUseExistingSockets(SocketType rtpsocket, SocketType rtcpsocket)
{
rtpsock = rtpsocket;
rtcpsock = rtcpsocket;
useexistingsockets = true;
}
/** If non null, the specified abort descriptors will be used to cancel
* the function that's waiting for packets to arrive; set to null (the default
* to let the transmitter create its own instance. */
void SetCreatedAbortDescriptors(RTPAbortDescriptors *desc)
{
m_pAbortDesc = desc;
}
/** Returns the RTP socket's send buffer size. */
int GetRTPSendBuffer() const
{
return rtpsendbuf;
}
/** Returns the RTP socket's receive buffer size. */
int GetRTPReceiveBuffer() const
{
return rtprecvbuf;
}
/** Returns the RTCP socket's send buffer size. */
int GetRTCPSendBuffer() const
{
return rtcpsendbuf;
}
/** Returns the RTCP socket's receive buffer size. */
int GetRTCPReceiveBuffer() const
{
return rtcprecvbuf;
}
/** Returns a flag indicating if RTCP traffic will be multiplexed over the RTP channel. */
bool GetRTCPMultiplexing() const
{
return rtcpmux;
}
/** If true, any RTP portbase will be allowed, not just even numbers. */
bool GetAllowOddPortbase() const
{
return allowoddportbase;
}
/** If non-zero, the specified port will be used to receive RTCP traffic. */
uint16_t GetForcedRTCPPort() const
{
return forcedrtcpport;
}
/** Returns true and fills in sockets if existing sockets were set
* using RTPUDPv4TransmissionParams::SetUseExistingSockets. */
bool GetUseExistingSockets(SocketType &rtpsocket, SocketType &rtcpsocket) const
{
if (!useexistingsockets)
return false;
rtpsocket = rtpsock;
rtcpsocket = rtcpsock;
return true;
}
/** If non-null, this RTPAbortDescriptors instance will be used internally,
* which can be useful when creating your own poll thread for multiple
* sessions. */
RTPAbortDescriptors *GetCreatedAbortDescriptors() const
{
return m_pAbortDesc;
}
private:
uint16_t portbase;
uint32_t bindIP, mcastifaceIP;
std::list<uint32_t> localIPs;
uint8_t multicastTTL;
int rtpsendbuf, rtprecvbuf;
int rtcpsendbuf, rtcprecvbuf;
bool rtcpmux;
bool allowoddportbase;
uint16_t forcedrtcpport;
SocketType rtpsock, rtcpsock;
bool useexistingsockets;
RTPAbortDescriptors *m_pAbortDesc;
};
inline RTPUDPv4TransmissionParams::RTPUDPv4TransmissionParams() :
RTPTransmissionParams(RTPTransmitter::IPv4UDPProto)
{
portbase = RTPUDPV4TRANS_DEFAULTPORTBASE;
bindIP = 0;
multicastTTL = 1;
mcastifaceIP = 0;
rtpsendbuf = RTPUDPV4TRANS_RTPTRANSMITBUFFER;
rtprecvbuf = RTPUDPV4TRANS_RTPRECEIVEBUFFER;
rtcpsendbuf = RTPUDPV4TRANS_RTCPTRANSMITBUFFER;
rtcprecvbuf = RTPUDPV4TRANS_RTCPRECEIVEBUFFER;
rtcpmux = false;
allowoddportbase = false;
forcedrtcpport = 0;
useexistingsockets = false;
rtpsock = 0;
rtcpsock = 0;
m_pAbortDesc = 0;
}
/** Additional information about the UDP over IPv4 transmitter. */
class QRTPLIB_API RTPUDPv4TransmissionInfo: public RTPTransmissionInfo
{
public:
RTPUDPv4TransmissionInfo(std::list<uint32_t> iplist, SocketType rtpsock, SocketType rtcpsock, uint16_t rtpport, uint16_t rtcpport) :
RTPTransmissionInfo(RTPTransmitter::IPv4UDPProto)
{
localIPlist = iplist;
rtpsocket = rtpsock;
rtcpsocket = rtcpsock;
m_rtpPort = rtpport;
m_rtcpPort = rtcpport;
}
~RTPUDPv4TransmissionInfo()
{
}
/** Returns the list of IPv4 addresses the transmitter considers to be the local IP addresses. */
std::list<uint32_t> GetLocalIPList() const
{
return localIPlist;
}
/** Returns the socket descriptor used for receiving and transmitting RTP packets. */
SocketType GetRTPSocket() const
{
return rtpsocket;
}
/** Returns the socket descriptor used for receiving and transmitting RTCP packets. */
SocketType GetRTCPSocket() const
{
return rtcpsocket;
}
/** Returns the port number that the RTP socket receives packets on. */
uint16_t GetRTPPort() const
{
return m_rtpPort;
}
/** Returns the port number that the RTCP socket receives packets on. */
uint16_t GetRTCPPort() const
{
return m_rtcpPort;
}
private:
std::list<uint32_t> localIPlist;
SocketType rtpsocket, rtcpsocket;
uint16_t m_rtpPort, m_rtcpPort;
};
class RTPUDPv4Trans_GetHashIndex_IPv4Dest
{
public:
static int GetIndex(const RTPIPv4Destination &d)
{
return d.GetIP() % RTPUDPV4TRANS_HASHSIZE;
}
};
class RTPUDPv4Trans_GetHashIndex_uint32_t
{
public:
static int GetIndex(const uint32_t &k)
{
return k % RTPUDPV4TRANS_HASHSIZE;
}
};
#define RTPUDPV4TRANS_HEADERSIZE (20+8)
/** An UDP over IPv4 transmission component.
* This class inherits the RTPTransmitter interface and implements a transmission component
* which uses UDP over IPv4 to send and receive RTP and RTCP data. The component's parameters
* are described by the class RTPUDPv4TransmissionParams. The functions which have an RTPAddress
* argument require an argument of RTPIPv4Address. The GetTransmissionInfo member function
* returns an instance of type RTPUDPv4TransmissionInfo.
*/
class QRTPLIB_API RTPUDPv4Transmitter: public RTPTransmitter
{
public:
RTPUDPv4Transmitter();
~RTPUDPv4Transmitter();
int Init(bool treadsafe);
int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams);
void Destroy();
RTPTransmissionInfo *GetTransmissionInfo();
void DeleteTransmissionInfo(RTPTransmissionInfo *inf);
int GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength);
bool ComesFromThisTransmitter(const RTPAddress *addr);
std::size_t GetHeaderOverhead()
{
return RTPUDPV4TRANS_HEADERSIZE;
}
int Poll();
int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0);
int AbortWait();
int SendRTPData(const void *data, std::size_t len);
int SendRTCPData(const void *data, std::size_t len);
int AddDestination(const RTPAddress &addr);
int DeleteDestination(const RTPAddress &addr);
void ClearDestinations();
bool SupportsMulticasting();
int JoinMulticastGroup(const RTPAddress &addr);
int LeaveMulticastGroup(const RTPAddress &addr);
void LeaveAllMulticastGroups();
int SetReceiveMode(RTPTransmitter::ReceiveMode m);
int AddToIgnoreList(const RTPAddress &addr);
int DeleteFromIgnoreList(const RTPAddress &addr);
void ClearIgnoreList();
int AddToAcceptList(const RTPAddress &addr);
int DeleteFromAcceptList(const RTPAddress &addr);
void ClearAcceptList();
int SetMaximumPacketSize(std::size_t s);
bool NewDataAvailable();
RTPRawPacket *GetNextPacket();
private:
int CreateLocalIPList();
bool GetLocalIPList_Interfaces();
void GetLocalIPList_DNS();
void AddLoopbackAddress();
void FlushPackets();
int PollSocket(bool rtp);
int ProcessAddAcceptIgnoreEntry(uint32_t ip, uint16_t port);
int ProcessDeleteAcceptIgnoreEntry(uint32_t ip, uint16_t port);
#ifdef RTP_SUPPORT_IPV4MULTICAST
bool SetMulticastTTL(uint8_t ttl);
#endif // RTP_SUPPORT_IPV4MULTICAST
bool ShouldAcceptData(uint32_t srcip, uint16_t srcport);
void ClearAcceptIgnoreInfo();
int GetAutoSockets(uint32_t bindIP, bool allowOdd, bool rtcpMux, SocketType *pRtpSock, SocketType *pRtcpSock, uint16_t *pRtpPort, uint16_t *pRtcpPort);
static int GetIPv4SocketPort(SocketType s, uint16_t *pPort);
bool init;
bool created;
bool waitingfordata;
SocketType rtpsock, rtcpsock;
uint32_t mcastifaceIP;
std::list<uint32_t> localIPs;
uint16_t m_rtpPort, m_rtcpPort;
uint8_t multicastTTL;
RTPTransmitter::ReceiveMode receivemode;
uint8_t *localhostname;
std::size_t localhostnamelength;
RTPHashTable<const RTPIPv4Destination, RTPUDPv4Trans_GetHashIndex_IPv4Dest, RTPUDPV4TRANS_HASHSIZE> destinations;
#ifdef RTP_SUPPORT_IPV4MULTICAST
RTPHashTable<const uint32_t, RTPUDPv4Trans_GetHashIndex_uint32_t, RTPUDPV4TRANS_HASHSIZE> multicastgroups;
#endif // RTP_SUPPORT_IPV4MULTICAST
std::list<RTPRawPacket*> rawpacketlist;
bool supportsmulticasting;
std::size_t maxpacksize;
class PortInfo
{
public:
PortInfo()
{
all = false;
}
bool all;
std::list<uint16_t> portlist;
};
RTPKeyHashTable<const uint32_t, PortInfo*, RTPUDPv4Trans_GetHashIndex_uint32_t, RTPUDPV4TRANS_HASHSIZE> acceptignoreinfo;
bool closesocketswhendone;
RTPAbortDescriptors m_abortDesc;
RTPAbortDescriptors *m_pAbortDesc; // in case an external one was specified
};
} // end namespace
#endif // RTPUDPV4TRANSMITTER_H

File diff suppressed because it is too large Load Diff

View File

@ -1,492 +0,0 @@
/*
This file is a part of JRTPLIB
Copyright (c) 1999-2017 Jori Liesenborgs
Contact: jori.liesenborgs@gmail.com
This library was developed at the Expertise Centre for Digital Media
(http://www.edm.uhasselt.be), a research center of the Hasselt University
(http://www.uhasselt.be). The library is based upon work done for
my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/
/**
* \file rtpudpv4transmitternobind.h
*/
#ifndef RTPUDPV4TRANSMITTERNOBIND_H
#define RTPUDPV4TRANSMITTERNOBIND_H
#include "rtpconfig.h"
#include "rtptransmitter.h"
#include "rtpipv4destination.h"
#include "rtphashtable.h"
#include "rtpkeyhashtable.h"
#include "rtpsocketutil.h"
#include "rtpabortdescriptors.h"
#include <list>
#include "util/export.h"
#define RTPUDPV4TRANSNOBIND_HASHSIZE 8317
#define RTPUDPV4TRANSNOBIND_DEFAULTPORTBASE 5000
#define RTPUDPV4TRANSNOBIND_RTPRECEIVEBUFFER 32768
#define RTPUDPV4TRANSNOBIND_RTCPRECEIVEBUFFER 32768
#define RTPUDPV4TRANSNOBIND_RTPTRANSMITBUFFER 32768
#define RTPUDPV4TRANSNOBIND_RTCPTRANSMITBUFFER 32768
namespace qrtplib
{
/** Parameters for the UDP over IPv4 transmitter that does not automatically bind sockets */
class QRTPLIB_API RTPUDPv4TransmissionNoBindParams: public RTPTransmissionParams
{
public:
RTPUDPv4TransmissionNoBindParams();
/** Sets the IP address which is used to bind the sockets to \c ip. */
void SetBindIP(uint32_t ip)
{
bindIP = ip;
}
/** Sets the multicast interface IP address. */
void SetMulticastInterfaceIP(uint32_t ip)
{
mcastifaceIP = ip;
}
/** Sets the RTP portbase to \c pbase, which has to be an even number
* unless RTPUDPv4TransmissionParams::SetAllowOddPortbase was called;
* a port number of zero will cause a port to be chosen automatically. */
void SetPortbase(uint16_t pbase)
{
portbase = pbase;
}
/** Sets the multicast TTL to be used to \c mcastTTL. */
void SetMulticastTTL(uint8_t mcastTTL)
{
multicastTTL = mcastTTL;
}
/** Passes a list of IP addresses which will be used as the local IP addresses. */
void SetLocalIPList(std::list<uint32_t> &iplist)
{
localIPs = iplist;
}
/** Clears the list of local IP addresses.
* Clears the list of local IP addresses. An empty list will make the transmission
* component itself determine the local IP addresses.
*/
void ClearLocalIPList()
{
localIPs.clear();
}
/** Returns the IP address which will be used to bind the sockets. */
uint32_t GetBindIP() const
{
return bindIP;
}
/** Returns the multicast interface IP address. */
uint32_t GetMulticastInterfaceIP() const
{
return mcastifaceIP;
}
/** Returns the RTP portbase which will be used (default is 5000). */
uint16_t GetPortbase() const
{
return portbase;
}
/** Returns the multicast TTL which will be used (default is 1). */
uint8_t GetMulticastTTL() const
{
return multicastTTL;
}
/** Returns the list of local IP addresses. */
const std::list<uint32_t> &GetLocalIPList() const
{
return localIPs;
}
/** Sets the RTP socket's send buffer size. */
void SetRTPSendBuffer(int s)
{
rtpsendbuf = s;
}
/** Sets the RTP socket's receive buffer size. */
void SetRTPReceiveBuffer(int s)
{
rtprecvbuf = s;
}
/** Sets the RTCP socket's send buffer size. */
void SetRTCPSendBuffer(int s)
{
rtcpsendbuf = s;
}
/** Sets the RTCP socket's receive buffer size. */
void SetRTCPReceiveBuffer(int s)
{
rtcprecvbuf = s;
}
/** Enables or disables multiplexing RTCP traffic over the RTP channel, so that only a single port is used. */
void SetRTCPMultiplexing(bool f)
{
rtcpmux = f;
}
/** Can be used to allow the RTP port base to be any number, not just even numbers. */
void SetAllowOddPortbase(bool f)
{
allowoddportbase = f;
}
/** Force the RTCP socket to use a specific port, not necessarily one more than
* the RTP port (set this to zero to disable). */
void SetForcedRTCPPort(uint16_t rtcpport)
{
forcedrtcpport = rtcpport;
}
/** Use sockets that have already been created, no checks on port numbers
* will be done, and no buffer sizes will be set; you'll need to close
* the sockets yourself when done, it will **not** be done automatically. */
void SetUseExistingSockets(SocketType rtpsocket, SocketType rtcpsocket)
{
rtpsock = rtpsocket;
rtcpsock = rtcpsocket;
useexistingsockets = true;
}
/** If non null, the specified abort descriptors will be used to cancel
* the function that's waiting for packets to arrive; set to null (the default
* to let the transmitter create its own instance. */
void SetCreatedAbortDescriptors(RTPAbortDescriptors *desc)
{
m_pAbortDesc = desc;
}
/** Returns the RTP socket's send buffer size. */
int GetRTPSendBuffer() const
{
return rtpsendbuf;
}
/** Returns the RTP socket's receive buffer size. */
int GetRTPReceiveBuffer() const
{
return rtprecvbuf;
}
/** Returns the RTCP socket's send buffer size. */
int GetRTCPSendBuffer() const
{
return rtcpsendbuf;
}
/** Returns the RTCP socket's receive buffer size. */
int GetRTCPReceiveBuffer() const
{
return rtcprecvbuf;
}
/** Returns a flag indicating if RTCP traffic will be multiplexed over the RTP channel. */
bool GetRTCPMultiplexing() const
{
return rtcpmux;
}
/** If true, any RTP portbase will be allowed, not just even numbers. */
bool GetAllowOddPortbase() const
{
return allowoddportbase;
}
/** If non-zero, the specified port will be used to receive RTCP traffic. */
uint16_t GetForcedRTCPPort() const
{
return forcedrtcpport;
}
/** Returns true and fills in sockets if existing sockets were set
* using RTPUDPv4TransmissionParams::SetUseExistingSockets. */
bool GetUseExistingSockets(SocketType &rtpsocket, SocketType &rtcpsocket) const
{
if (!useexistingsockets)
return false;
rtpsocket = rtpsock;
rtcpsocket = rtcpsock;
return true;
}
/** If non-null, this RTPAbortDescriptors instance will be used internally,
* which can be useful when creating your own poll thread for multiple
* sessions. */
RTPAbortDescriptors *GetCreatedAbortDescriptors() const
{
return m_pAbortDesc;
}
private:
uint16_t portbase;
uint32_t bindIP, mcastifaceIP;
std::list<uint32_t> localIPs;
uint8_t multicastTTL;
int rtpsendbuf, rtprecvbuf;
int rtcpsendbuf, rtcprecvbuf;
bool rtcpmux;
bool allowoddportbase;
uint16_t forcedrtcpport;
SocketType rtpsock, rtcpsock;
bool useexistingsockets;
RTPAbortDescriptors *m_pAbortDesc;
};
inline RTPUDPv4TransmissionNoBindParams::RTPUDPv4TransmissionNoBindParams() :
RTPTransmissionParams(RTPTransmitter::IPv4UDPProto)
{
portbase = RTPUDPV4TRANSNOBIND_DEFAULTPORTBASE;
bindIP = 0;
multicastTTL = 1;
mcastifaceIP = 0;
rtpsendbuf = RTPUDPV4TRANSNOBIND_RTPTRANSMITBUFFER;
rtprecvbuf = RTPUDPV4TRANSNOBIND_RTPRECEIVEBUFFER;
rtcpsendbuf = RTPUDPV4TRANSNOBIND_RTCPTRANSMITBUFFER;
rtcprecvbuf = RTPUDPV4TRANSNOBIND_RTCPRECEIVEBUFFER;
rtcpmux = false;
allowoddportbase = false;
forcedrtcpport = 0;
useexistingsockets = false;
rtpsock = 0;
rtcpsock = 0;
m_pAbortDesc = 0;
}
/** Additional information about the UDP over IPv4 transmitter that does not automatically bind sockets. */
class QRTPLIB_API RTPUDPv4TransmissionNoBindInfo: public RTPTransmissionInfo
{
public:
RTPUDPv4TransmissionNoBindInfo(const QHostAddress& ip, SocketType rtpsock, SocketType rtcpsock, uint16_t rtpport, uint16_t rtcpport) :
RTPTransmissionInfo(RTPTransmitter::IPv4UDPProto)
{
localIP = ip;
rtpsocket = rtpsock;
rtcpsocket = rtcpsock;
m_rtpPort = rtpport;
m_rtcpPort = rtcpport;
}
~RTPUDPv4TransmissionNoBindInfo()
{
}
/** Returns the list of IPv4 addresses the transmitter considers to be the local IP addresses. */
QHostAddress GetLocalIP() const
{
return localIP;
}
/** Returns the socket descriptor used for receiving and transmitting RTP packets. */
SocketType GetRTPSocket() const
{
return rtpsocket;
}
/** Returns the socket descriptor used for receiving and transmitting RTCP packets. */
SocketType GetRTCPSocket() const
{
return rtcpsocket;
}
/** Returns the port number that the RTP socket receives packets on. */
uint16_t GetRTPPort() const
{
return m_rtpPort;
}
/** Returns the port number that the RTCP socket receives packets on. */
uint16_t GetRTCPPort() const
{
return m_rtcpPort;
}
private:
QHostAddress localIP;
SocketType rtpsocket, rtcpsocket;
uint16_t m_rtpPort, m_rtcpPort;
};
class RTPUDPv4TransNoBind_GetHashIndex_IPv4Dest
{
public:
static int GetIndex(const RTPIPv4Destination &d)
{
return d.GetIP() % RTPUDPV4TRANSNOBIND_HASHSIZE;
}
};
class RTPUDPv4TransNoBind_GetHashIndex_uint32_t
{
public:
static int GetIndex(const uint32_t &k)
{
return k % RTPUDPV4TRANSNOBIND_HASHSIZE;
}
};
#define RTPUDPV4TRANSNOBIND_HEADERSIZE (20+8)
/** An UDP over IPv4 transmission component.
* This class inherits the RTPTransmitter interface and implements a transmission component
* which uses UDP over IPv4 to send and receive RTP and RTCP data. The component's parameters
* are described by the class RTPUDPv4TransmissionNoBindParams. The functions which have an RTPAddress
* argument require an argument of RTPIPv4Address. The GetTransmissionInfo member function
* returns an instance of type RTPUDPv4TransmissionNoBindInfo.
* This flavor of a RTPUDPv4Transmitter class does not automatically bind sockets. Use the
* BindSockets method to do so.
*/
class QRTPLIB_API RTPUDPv4TransmitterNoBind: public RTPTransmitter
{
public:
RTPUDPv4TransmitterNoBind();
~RTPUDPv4TransmitterNoBind();
int Init(bool treadsafe);
int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams);
/** Bind the RTP and RTCP sockets to ports defined in the transmission parameters */
int BindSockets(const RTPTransmissionParams *transparams);
void Destroy();
RTPTransmissionInfo *GetTransmissionInfo();
void DeleteTransmissionInfo(RTPTransmissionInfo *inf);
int GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength);
bool ComesFromThisTransmitter(const RTPAddress *addr);
std::size_t GetHeaderOverhead()
{
return RTPUDPV4TRANSNOBIND_HEADERSIZE;
}
int Poll();
int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0);
int AbortWait();
int SendRTPData(const void *data, std::size_t len);
int SendRTCPData(const void *data, std::size_t len);
int AddDestination(const RTPAddress &addr);
int DeleteDestination(const RTPAddress &addr);
void ClearDestinations();
bool SupportsMulticasting();
int JoinMulticastGroup(const RTPAddress &addr);
int LeaveMulticastGroup(const RTPAddress &addr);
void LeaveAllMulticastGroups();
int SetReceiveMode(RTPTransmitter::ReceiveMode m);
int AddToIgnoreList(const RTPAddress &addr);
int DeleteFromIgnoreList(const RTPAddress &addr);
void ClearIgnoreList();
int AddToAcceptList(const RTPAddress &addr);
int DeleteFromAcceptList(const RTPAddress &addr);
void ClearAcceptList();
int SetMaximumPacketSize(std::size_t s);
bool NewDataAvailable();
RTPRawPacket *GetNextPacket();
private:
int CreateLocalIPList();
bool GetLocalIPList_Interfaces();
void GetLocalIPList_DNS();
void AddLoopbackAddress();
void FlushPackets();
int PollSocket(bool rtp);
int ProcessAddAcceptIgnoreEntry(uint32_t ip, uint16_t port);
int ProcessDeleteAcceptIgnoreEntry(uint32_t ip, uint16_t port);
#ifdef RTP_SUPPORT_IPV4MULTICAST
bool SetMulticastTTL(uint8_t ttl);
#endif // RTP_SUPPORT_IPV4MULTICAST
bool ShouldAcceptData(uint32_t srcip, uint16_t srcport);
void ClearAcceptIgnoreInfo();
int GetAutoSockets(uint32_t bindIP, bool allowOdd, bool rtcpMux, SocketType *pRtpSock, SocketType *pRtcpSock, uint16_t *pRtpPort, uint16_t *pRtcpPort);
static int GetIPv4SocketPort(SocketType s, uint16_t *pPort);
bool init;
bool created;
bool waitingfordata;
SocketType rtpsock, rtcpsock;
uint32_t mcastifaceIP;
std::list<uint32_t> localIPs;
uint16_t m_rtpPort, m_rtcpPort;
uint8_t multicastTTL;
RTPTransmitter::ReceiveMode receivemode;
uint8_t *localhostname;
std::size_t localhostnamelength;
RTPHashTable<const RTPIPv4Destination, RTPUDPv4TransNoBind_GetHashIndex_IPv4Dest, RTPUDPV4TRANSNOBIND_HASHSIZE> destinations;
#ifdef RTP_SUPPORT_IPV4MULTICAST
RTPHashTable<const uint32_t, RTPUDPv4TransNoBind_GetHashIndex_uint32_t, RTPUDPV4TRANSNOBIND_HASHSIZE> multicastgroups;
#endif // RTP_SUPPORT_IPV4MULTICAST
std::list<RTPRawPacket*> rawpacketlist;
bool supportsmulticasting;
std::size_t maxpacksize;
class PortInfo
{
public:
PortInfo()
{
all = false;
}
bool all;
std::list<uint16_t> portlist;
};
RTPKeyHashTable<const uint32_t, PortInfo*, RTPUDPv4TransNoBind_GetHashIndex_uint32_t, RTPUDPV4TRANSNOBIND_HASHSIZE> acceptignoreinfo;
bool closesocketswhendone;
RTPAbortDescriptors m_abortDesc;
RTPAbortDescriptors *m_pAbortDesc; // in case an external one was specified
};
} // end namespace
#endif // RTPUDPV4TRANSMITTERNOBIND_H