mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-24 03:02:29 -04:00
qrtplib: file cleanup
This commit is contained in:
parent
914b8a4d97
commit
915b865e6a
@ -19,12 +19,8 @@ set (qrtplib_HEADERS
|
|||||||
rtpdefines.h
|
rtpdefines.h
|
||||||
rtpendian.h
|
rtpendian.h
|
||||||
rtperrors.h
|
rtperrors.h
|
||||||
rtphashtable.h
|
|
||||||
rtpinternalsourcedata.h
|
rtpinternalsourcedata.h
|
||||||
# rtpipv4address.h
|
|
||||||
# rtpipv4destination.h
|
|
||||||
rtpkeyhashtable.h
|
rtpkeyhashtable.h
|
||||||
rtplibraryversion.h
|
|
||||||
rtppacket.h
|
rtppacket.h
|
||||||
rtppacketbuilder.h
|
rtppacketbuilder.h
|
||||||
rtprandom.h
|
rtprandom.h
|
||||||
@ -43,14 +39,7 @@ set (qrtplib_HEADERS
|
|||||||
rtptypes_win.h
|
rtptypes_win.h
|
||||||
rtptypes.h
|
rtptypes.h
|
||||||
rtpudptransmitter.h
|
rtpudptransmitter.h
|
||||||
# rtpudpv4transmitter.h
|
|
||||||
# rtpudpv4transmitternobind.h
|
|
||||||
# rtpexternaltransmitter.h
|
|
||||||
rtpsocketutil.h
|
rtpsocketutil.h
|
||||||
rtpabortdescriptors.h
|
|
||||||
rtpselect.h
|
|
||||||
# rtptcpaddress.h
|
|
||||||
# rtptcptransmitter.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(qrtplib_SOURCES
|
set(qrtplib_SOURCES
|
||||||
@ -68,9 +57,6 @@ set(qrtplib_SOURCES
|
|||||||
rtpcollisionlist.cpp
|
rtpcollisionlist.cpp
|
||||||
rtperrors.cpp
|
rtperrors.cpp
|
||||||
rtpinternalsourcedata.cpp
|
rtpinternalsourcedata.cpp
|
||||||
# rtpipv4address.cpp
|
|
||||||
# rtpipv4destination.cpp
|
|
||||||
rtplibraryversion.cpp
|
|
||||||
rtppacket.cpp
|
rtppacket.cpp
|
||||||
rtppacketbuilder.cpp
|
rtppacketbuilder.cpp
|
||||||
rtprandom.cpp
|
rtprandom.cpp
|
||||||
@ -84,12 +70,6 @@ set(qrtplib_SOURCES
|
|||||||
rtpsources.cpp
|
rtpsources.cpp
|
||||||
rtptimeutilities.cpp
|
rtptimeutilities.cpp
|
||||||
rtpudptransmitter.cpp
|
rtpudptransmitter.cpp
|
||||||
# rtpudpv4transmitter.cpp
|
|
||||||
# rtpudpv4transmitternobind.cpp
|
|
||||||
# rtpexternaltransmitter.cpp
|
|
||||||
rtpabortdescriptors.cpp
|
|
||||||
# rtptcpaddress.cpp
|
|
||||||
# rtptcptransmitter.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
|
@ -40,10 +40,7 @@ HEADERS += $$PWD/rtcpapppacket.h \
|
|||||||
$$PWD/rtpdefines.h \
|
$$PWD/rtpdefines.h \
|
||||||
$$PWD/rtpendian.h \
|
$$PWD/rtpendian.h \
|
||||||
$$PWD/rtperrors.h \
|
$$PWD/rtperrors.h \
|
||||||
$$PWD/rtphashtable.h \
|
|
||||||
$$PWD/rtpinternalsourcedata.h \
|
$$PWD/rtpinternalsourcedata.h \
|
||||||
$$PWD/rtpkeyhashtable.h \
|
|
||||||
$$PWD/rtplibraryversion.h \
|
|
||||||
$$PWD/rtppacket.h \
|
$$PWD/rtppacket.h \
|
||||||
$$PWD/rtppacketbuilder.h \
|
$$PWD/rtppacketbuilder.h \
|
||||||
$$PWD/rtprandom.h \
|
$$PWD/rtprandom.h \
|
||||||
@ -80,7 +77,6 @@ SOURCES += $$PWD/rtcpapppacket.cpp \
|
|||||||
$$PWD/rtpcollisionlist.cpp \
|
$$PWD/rtpcollisionlist.cpp \
|
||||||
$$PWD/rtperrors.cpp \
|
$$PWD/rtperrors.cpp \
|
||||||
$$PWD/rtpinternalsourcedata.cpp \
|
$$PWD/rtpinternalsourcedata.cpp \
|
||||||
$$PWD/rtplibraryversion.cpp \
|
|
||||||
$$PWD/rtppacket.cpp \
|
$$PWD/rtppacket.cpp \
|
||||||
$$PWD/rtppacketbuilder.cpp \
|
$$PWD/rtppacketbuilder.cpp \
|
||||||
$$PWD/rtprandom.cpp \
|
$$PWD/rtprandom.cpp \
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
@ -39,7 +39,6 @@
|
|||||||
#define RTPSESSION_H
|
#define RTPSESSION_H
|
||||||
|
|
||||||
#include "rtpconfig.h"
|
#include "rtpconfig.h"
|
||||||
#include "rtplibraryversion.h"
|
|
||||||
#include "rtppacketbuilder.h"
|
#include "rtppacketbuilder.h"
|
||||||
#include "rtpsessionsources.h"
|
#include "rtpsessionsources.h"
|
||||||
#include "rtptransmitter.h"
|
#include "rtptransmitter.h"
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
@ -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
@ -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
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user