From 354d5b3b5a355737b60d9849d18abb3ed5ac031c Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 22 Feb 2018 18:43:28 +0100 Subject: [PATCH] qrtplib: draft (1) --- CMakeLists.txt | 1 + qrtplib/CMakeLists.txt | 41 +++++ qrtplib/rtpdefines.h | 78 +++++++++ qrtplib/rtperrors.cpp | 276 ++++++++++++++++++++++++++++++ qrtplib/rtperrors.h | 253 +++++++++++++++++++++++++++ qrtplib/rtpinternalutils.h | 61 +++++++ qrtplib/rtppacketbuilder.cpp | 286 +++++++++++++++++++++++++++++++ qrtplib/rtppacketbuilder.h | 275 +++++++++++++++++++++++++++++ qrtplib/rtprandom.cpp | 90 ++++++++++ qrtplib/rtprandom.h | 82 +++++++++ qrtplib/rtprandomrand48.cpp | 89 ++++++++++ qrtplib/rtprandomrand48.h | 71 ++++++++ qrtplib/rtprandomurandom.cpp | 121 +++++++++++++ qrtplib/rtprandomurandom.h | 70 ++++++++ qrtplib/rtptimeutilities.cpp | 46 +++++ qrtplib/rtptimeutilities.h | 323 +++++++++++++++++++++++++++++++++++ 16 files changed, 2163 insertions(+) create mode 100644 qrtplib/CMakeLists.txt create mode 100644 qrtplib/rtpdefines.h create mode 100644 qrtplib/rtperrors.cpp create mode 100644 qrtplib/rtperrors.h create mode 100644 qrtplib/rtpinternalutils.h create mode 100644 qrtplib/rtppacketbuilder.cpp create mode 100644 qrtplib/rtppacketbuilder.h create mode 100644 qrtplib/rtprandom.cpp create mode 100644 qrtplib/rtprandom.h create mode 100644 qrtplib/rtprandomrand48.cpp create mode 100644 qrtplib/rtprandomrand48.h create mode 100644 qrtplib/rtprandomurandom.cpp create mode 100644 qrtplib/rtprandomurandom.h create mode 100644 qrtplib/rtptimeutilities.cpp create mode 100644 qrtplib/rtptimeutilities.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f814dfa39..96d1b840a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,6 +213,7 @@ add_subdirectory(sdrgui) add_subdirectory(sdrsrv) add_subdirectory(httpserver) add_subdirectory(logging) +add_subdirectory(qrtplib) add_subdirectory(swagger) include_directories( diff --git a/qrtplib/CMakeLists.txt b/qrtplib/CMakeLists.txt new file mode 100644 index 000000000..65dcc3bb7 --- /dev/null +++ b/qrtplib/CMakeLists.txt @@ -0,0 +1,41 @@ +project(qrtplib) + +set(qrtplib_SOURCES + rtptimeutilities.cpp + rtprandomurandom.cpp + rtprandomrand48.cpp + rtprandom.cpp + rtperrors.cpp +) + +set(qrtplib_HEADERS + rtptimeutilities.h + rtprandom.h + rtprandomurandom.h + rtprandomrand48.h + rtprandom.h + rtpinternalutils.h + rtperrors.h + rtpdefines.h +) + +include_directories( + . + ${CMAKE_CURRENT_BINARY_DIR} +) + +add_definitions(${QT_DEFINITIONS}) +add_definitions(-DQT_SHARED) + +add_library(qrtplib SHARED + ${qrtplib_SOURCES} + ${qrtplib_HEADERS_MOC} +) + +target_link_libraries(qrtplib + ${QT_LIBRARIES} +) + +qt5_use_modules(qrtplib Core Network) + +install(TARGETS qrtplib DESTINATION lib) diff --git a/qrtplib/rtpdefines.h b/qrtplib/rtpdefines.h new file mode 100644 index 000000000..c1d39af42 --- /dev/null +++ b/qrtplib/rtpdefines.h @@ -0,0 +1,78 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 RTPDEFINES_H + +#define RTPDEFINES_H + +#define RTP_VERSION 2 +#define RTP_MAXCSRCS 15 +#define RTP_MINPACKETSIZE 600 +#define RTP_DEFAULTPACKETSIZE 1400 +#define RTP_PROBATIONCOUNT 2 +#define RTP_MAXPRIVITEMS 256 +#define RTP_SENDERTIMEOUTMULTIPLIER 2 +#define RTP_BYETIMEOUTMULTIPLIER 1 +#define RTP_MEMBERTIMEOUTMULTIPLIER 5 +#define RTP_COLLISIONTIMEOUTMULTIPLIER 10 +#define RTP_NOTETTIMEOUTMULTIPLIER 25 +#define RTP_DEFAULTSESSIONBANDWIDTH 10000.0 + +#define RTP_RTCPTYPE_SR 200 +#define RTP_RTCPTYPE_RR 201 +#define RTP_RTCPTYPE_SDES 202 +#define RTP_RTCPTYPE_BYE 203 +#define RTP_RTCPTYPE_APP 204 + +#define RTCP_SDES_ID_CNAME 1 +#define RTCP_SDES_ID_NAME 2 +#define RTCP_SDES_ID_EMAIL 3 +#define RTCP_SDES_ID_PHONE 4 +#define RTCP_SDES_ID_LOCATION 5 +#define RTCP_SDES_ID_TOOL 6 +#define RTCP_SDES_ID_NOTE 7 +#define RTCP_SDES_ID_PRIVATE 8 +#define RTCP_SDES_NUMITEMS_NONPRIVATE 7 +#define RTCP_SDES_MAXITEMLENGTH 255 + +#define RTCP_BYE_MAXREASONLENGTH 255 +#define RTCP_DEFAULTMININTERVAL 5.0 +#define RTCP_DEFAULTBANDWIDTHFRACTION 0.05 +#define RTCP_DEFAULTSENDERFRACTION 0.25 +#define RTCP_DEFAULTHALFATSTARTUP true +#define RTCP_DEFAULTIMMEDIATEBYE true +#define RTCP_DEFAULTSRBYE true + +#endif // RTPDEFINES_H + diff --git a/qrtplib/rtperrors.cpp b/qrtplib/rtperrors.cpp new file mode 100644 index 000000000..1b0eb4068 --- /dev/null +++ b/qrtplib/rtperrors.cpp @@ -0,0 +1,276 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 "rtperrors.h" +#include "rtpdefines.h" +#include "rtpinternalutils.h" +#include + +//#include "rtpdebug.h" + +namespace qrtplib +{ + +struct RTPErrorInfo +{ + int code; + const char *description; +}; + +static RTPErrorInfo ErrorDescriptions[]= +{ + { ERR_RTP_OUTOFMEM,"Out of memory" }, + { ERR_RTP_NOTHREADSUPPORT, "No JThread support was compiled in"}, + { ERR_RTP_COLLISIONLIST_BADADDRESS, "Passed invalid address (null) to collision list"}, + { ERR_RTP_HASHTABLE_ELEMENTALREADYEXISTS, "Element already exists in hash table"}, + { ERR_RTP_HASHTABLE_ELEMENTNOTFOUND, "Element not found in hash table"}, + { ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX, "Function returned an illegal hash index"}, + { ERR_RTP_HASHTABLE_NOCURRENTELEMENT, "No current element selected in hash table"}, + { ERR_RTP_KEYHASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX, "Function returned an illegal hash index"}, + { ERR_RTP_KEYHASHTABLE_KEYALREADYEXISTS, "Key value already exists in key hash table"}, + { ERR_RTP_KEYHASHTABLE_KEYNOTFOUND, "Key value not found in key hash table"}, + { ERR_RTP_KEYHASHTABLE_NOCURRENTELEMENT, "No current element selected in key hash table"}, + { ERR_RTP_PACKBUILD_ALREADYINIT, "RTP packet builder is already initialized"}, + { ERR_RTP_PACKBUILD_CSRCALREADYINLIST, "The specified CSRC is already in the RTP packet builder's CSRC list"}, + { ERR_RTP_PACKBUILD_CSRCLISTFULL, "The RTP packet builder's CSRC list already contains 15 entries"}, + { ERR_RTP_PACKBUILD_CSRCNOTINLIST, "The specified CSRC was not found in the RTP packet builder's CSRC list"}, + { ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET, "The RTP packet builder's default mark flag is not set"}, + { ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET, "The RTP packet builder's default payload type is not set"}, + { ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET, "The RTP packet builder's default timestamp increment is not set"}, + { ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE, "The specified maximum packet size for the RTP packet builder is invalid"}, + { ERR_RTP_PACKBUILD_NOTINIT, "The RTP packet builder is not initialized"}, + { ERR_RTP_PACKET_BADPAYLOADTYPE, "Invalid payload type"}, + { ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE, "Tried to create an RTP packet which whould exceed the specified maximum packet size"}, + { ERR_RTP_PACKET_EXTERNALBUFFERNULL, "Illegal value (null) passed as external buffer for the RTP packet"}, + { ERR_RTP_PACKET_ILLEGALBUFFERSIZE, "Illegal buffer size specified for the RTP packet"}, + { ERR_RTP_PACKET_INVALIDPACKET, "Invalid RTP packet format"}, + { ERR_RTP_PACKET_TOOMANYCSRCS, "More than 15 CSRCs specified for the RTP packet"}, + { ERR_RTP_POLLTHREAD_ALREADYRUNNING, "Poll thread is already running"}, + { ERR_RTP_POLLTHREAD_CANTINITMUTEX, "Can't initialize a mutex for the poll thread"}, + { ERR_RTP_POLLTHREAD_CANTSTARTTHREAD, "Can't start the poll thread"}, + { ERR_RTP_RTCPCOMPOUND_INVALIDPACKET, "Invalid RTCP compound packet format"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILDING, "Already building this RTCP compound packet"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILT, "This RTCP compound packet is already built"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYGOTREPORT, "There's already a SR or RR in this RTCP compound packet"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG, "The specified APP data length for the RTCP compound packet is too big"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_BUFFERSIZETOOSMALL, "The specified buffer size for the RTCP comound packet is too small"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALAPPDATALENGTH, "The APP data length must be a multiple of four"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALSUBTYPE, "The APP packet subtype must be smaller than 32"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_INVALIDITEMTYPE, "Invalid SDES item type specified for the RTCP compound packet"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_MAXPACKETSIZETOOSMALL, "The specified maximum packet size for the RTCP compound packet is too small"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE, "Tried to add an SDES item to the RTCP compound packet when no SSRC was present"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_NOREPORTPRESENT, "An RTCP compound packet must contain a SR or RR"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING, "The RTCP compound packet builder is not initialized"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT, "Adding this data would exceed the specified maximum RTCP compound packet size"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_REPORTNOTSTARTED, "Tried to add a report block to the RTCP compound packet when no SR or RR was started"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_TOOMANYSSRCS, "Only 31 SSRCs will fit into a BYE packet for the RTCP compound packet"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_TOTALITEMLENGTHTOOBIG, "The total data for the SDES PRIV item exceeds the maximum size (255 bytes) of an SDES item"}, + { ERR_RTP_RTCPPACKETBUILDER_ALREADYINIT, "The RTCP packet builder is already initialized"}, + { ERR_RTP_RTCPPACKETBUILDER_ILLEGALMAXPACKSIZE, "The specified maximum packet size for the RTCP packet builder is too small"}, + { ERR_RTP_RTCPPACKETBUILDER_ILLEGALTIMESTAMPUNIT, "Speficied an illegal timestamp unit for the the RTCP packet builder"}, + { ERR_RTP_RTCPPACKETBUILDER_NOTINIT, "The RTCP packet builder was not initialized"}, + { ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON, "The RTCP compound packet filled sooner than expected"}, + { ERR_RTP_SCHEDPARAMS_BADFRACTION, "Illegal sender bandwidth fraction specified"}, + { ERR_RTP_SCHEDPARAMS_BADMINIMUMINTERVAL, "The minimum RTCP interval specified for the scheduler is too small"}, + { ERR_RTP_SCHEDPARAMS_INVALIDBANDWIDTH, "Invalid RTCP bandwidth specified for the RTCP scheduler"}, + { ERR_RTP_SDES_LENGTHTOOBIG, "Specified size for the SDES item exceeds 255 bytes"}, + { ERR_RTP_SDES_PREFIXNOTFOUND, "The specified SDES PRIV prefix was not found"}, + { ERR_RTP_SESSION_ALREADYCREATED, "The session is already created"}, + { ERR_RTP_SESSION_CANTGETLOGINNAME, "Can't retrieve login name"}, + { ERR_RTP_SESSION_CANTINITMUTEX, "A mutex for the RTP session couldn't be initialized"}, + { ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL, "The maximum packet size specified for the RTP session is too small"}, + { ERR_RTP_SESSION_NOTCREATED, "The RTP session was not created"}, + { ERR_RTP_SESSION_UNSUPPORTEDTRANSMISSIONPROTOCOL, "The requested transmission protocol for the RTP session is not supported"}, + { ERR_RTP_SESSION_USINGPOLLTHREAD, "This function is not available when using the RTP poll thread feature"}, + { ERR_RTP_SESSION_USERDEFINEDTRANSMITTERNULL, "A user-defined transmitter was requested but the supplied transmitter component is NULL"}, + { ERR_RTP_SOURCES_ALREADYHAVEOWNSSRC, "Only one source can be marked as own SSRC in the source table"}, + { ERR_RTP_SOURCES_DONTHAVEOWNSSRC, "No source was marked as own SSRC in the source table"}, + { ERR_RTP_SOURCES_ILLEGALSDESTYPE, "Illegal SDES type specified for processing into the source table"}, + { ERR_RTP_SOURCES_SSRCEXISTS, "Can't create own SSRC because this SSRC identifier is already in the source table"}, + { ERR_RTP_UDPV4TRANS_ALREADYCREATED, "The transmitter was already created"}, + { ERR_RTP_UDPV4TRANS_ALREADYINIT, "The transmitter was already initialize"}, + { ERR_RTP_UDPV4TRANS_ALREADYWAITING, "The transmitter is already waiting for incoming data"}, + { ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET, "The 'bind' call for the RTCP socket failed"}, + { ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET, "The 'bind' call for the RTP socket failed"}, + { ERR_RTP_UDPV4TRANS_CANTCREATESOCKET, "Couldn't create the RTP or RTCP socket"}, + { ERR_RTP_UDPV4TRANS_CANTINITMUTEX, "Failed to initialize a mutex used by the transmitter"}, + { ERR_RTP_UDPV4TRANS_CANTSETRTCPRECEIVEBUF, "Couldn't set the receive buffer size for the RTCP socket"}, + { ERR_RTP_UDPV4TRANS_CANTSETRTCPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTCP socket"}, + { ERR_RTP_UDPV4TRANS_CANTSETRTPRECEIVEBUF, "Couldn't set the receive buffer size for the RTP socket"}, + { ERR_RTP_UDPV4TRANS_CANTSETRTPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTP socket"}, + { ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP, "Unable to join the specified multicast group"}, + { ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE, "The function called doens't match the current receive mode"}, + { ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS, "Illegal parameters type passed to the transmitter"}, + { ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE, "Specified address type isn't compatible with this transmitter"}, + { ERR_RTP_UDPV4TRANS_NOLOCALIPS, "Couldn't determine the local host name since the local IP list is empty"}, + { ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT, "Multicast support is not available"}, + { ERR_RTP_UDPV4TRANS_NOSUCHENTRY, "Specified entry could not be found"}, + { ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS, "The specified address is not a multicast address"}, + { ERR_RTP_UDPV4TRANS_NOTCREATED, "The 'Create' call for this transmitter has not been called"}, + { ERR_RTP_UDPV4TRANS_NOTINIT, "The 'Init' call for this transmitter has not been called"}, + { ERR_RTP_UDPV4TRANS_NOTWAITING, "The transmitter is not waiting for incoming data"}, + { ERR_RTP_UDPV4TRANS_PORTBASENOTEVEN, "The specified port base is not an even number"}, + { ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG, "The maximum packet size is too big for this transmitter"}, + { ERR_RTP_UDPV6TRANS_ALREADYCREATED, "The transmitter was already created"}, + { ERR_RTP_UDPV6TRANS_ALREADYINIT, "The transmitter was already initialize"}, + { ERR_RTP_UDPV6TRANS_ALREADYWAITING, "The transmitter is already waiting for incoming data"}, + { ERR_RTP_UDPV6TRANS_CANTBINDRTCPSOCKET, "The 'bind' call for the RTCP socket failed"}, + { ERR_RTP_UDPV6TRANS_CANTBINDRTPSOCKET, "The 'bind' call for the RTP socket failed"}, + { ERR_RTP_UDPV6TRANS_CANTCREATESOCKET, "Couldn't create the RTP or RTCP socket"}, + { ERR_RTP_UDPV6TRANS_CANTINITMUTEX, "Failed to initialize a mutex used by the transmitter"}, + { ERR_RTP_UDPV6TRANS_CANTSETRTCPRECEIVEBUF, "Couldn't set the receive buffer size for the RTCP socket"}, + { ERR_RTP_UDPV6TRANS_CANTSETRTCPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTCP socket"}, + { ERR_RTP_UDPV6TRANS_CANTSETRTPRECEIVEBUF, "Couldn't set the receive buffer size for the RTP socket"}, + { ERR_RTP_UDPV6TRANS_CANTSETRTPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTP socket"}, + { ERR_RTP_UDPV6TRANS_COULDNTJOINMULTICASTGROUP, "Unable to join the specified multicast group"}, + { ERR_RTP_UDPV6TRANS_DIFFERENTRECEIVEMODE, "The function called doens't match the current receive mode"}, + { ERR_RTP_UDPV6TRANS_ILLEGALPARAMETERS, "Illegal parameters type passed to the transmitter"}, + { ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE, "Specified address type isn't compatible with this transmitter"}, + { ERR_RTP_UDPV6TRANS_NOLOCALIPS, "Couldn't determine the local host name since the local IP list is empty"}, + { ERR_RTP_UDPV6TRANS_NOMULTICASTSUPPORT, "Multicast support is not available"}, + { ERR_RTP_UDPV6TRANS_NOSUCHENTRY, "Specified entry could not be found"}, + { ERR_RTP_UDPV6TRANS_NOTAMULTICASTADDRESS, "The specified address is not a multicast address"}, + { ERR_RTP_UDPV6TRANS_NOTCREATED, "The 'Create' call for this transmitter has not been called"}, + { ERR_RTP_UDPV6TRANS_NOTINIT, "The 'Init' call for this transmitter has not been called"}, + { ERR_RTP_UDPV6TRANS_NOTWAITING, "The transmitter is not waiting for incoming data"}, + { ERR_RTP_UDPV6TRANS_PORTBASENOTEVEN, "The specified port base is not an even number"}, + { ERR_RTP_UDPV6TRANS_SPECIFIEDSIZETOOBIG, "The maximum packet size is too big for this transmitter"}, + { ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL,"The hostname is larger than the specified buffer size"}, + { ERR_RTP_SDES_MAXPRIVITEMS,"The maximum number of SDES private item prefixes was reached"}, + { ERR_RTP_INTERNALSOURCEDATA_INVALIDPROBATIONTYPE,"An invalid probation type was specified"}, + { ERR_RTP_FAKETRANS_ALREADYCREATED, "The transmitter was already created"}, + { ERR_RTP_FAKETRANS_ALREADYINIT, "The transmitter was already initialize"}, + { ERR_RTP_FAKETRANS_CANTINITMUTEX, "Failed to initialize a mutex used by the transmitter"}, + { ERR_RTP_FAKETRANS_COULDNTJOINMULTICASTGROUP, "Unable to join the specified multicast group"}, + { ERR_RTP_FAKETRANS_DIFFERENTRECEIVEMODE, "The function called doens't match the current receive mode"}, + { ERR_RTP_FAKETRANS_ILLEGALPARAMETERS, "Illegal parameters type passed to the transmitter"}, + { ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE, "Specified address type isn't compatible with this transmitter"}, + { ERR_RTP_FAKETRANS_NOLOCALIPS, "Couldn't determine the local host name since the local IP list is empty"}, + { ERR_RTP_FAKETRANS_NOMULTICASTSUPPORT, "Multicast support is not available"}, + { ERR_RTP_FAKETRANS_NOSUCHENTRY, "Specified entry could not be found"}, + { ERR_RTP_FAKETRANS_NOTAMULTICASTADDRESS, "The specified address is not a multicast address"}, + { ERR_RTP_FAKETRANS_NOTCREATED, "The 'Create' call for this transmitter has not been called"}, + { ERR_RTP_FAKETRANS_NOTINIT, "The 'Init' call for this transmitter has not been called"}, + { ERR_RTP_FAKETRANS_PORTBASENOTEVEN, "The specified port base is not an even number"}, + { ERR_RTP_FAKETRANS_SPECIFIEDSIZETOOBIG, "The maximum packet size is too big for this transmitter"}, + { ERR_RTP_FAKETRANS_WAITNOTIMPLEMENTED, "The WaitForIncomingData is not implemented in the Gst transmitter"}, + { ERR_RTP_RTPRANDOMURANDOM_CANTOPEN, "Unable to open /dev/urandom for reading"}, + { ERR_RTP_RTPRANDOMURANDOM_ALREADYOPEN, "The device /dev/urandom was already opened"}, + { ERR_RTP_RTPRANDOMRANDS_NOTSUPPORTED, "The rand_s call is not supported on this platform"}, + { ERR_RTP_EXTERNALTRANS_ALREADYCREATED, "The external transmission component was already created"}, + { ERR_RTP_EXTERNALTRANS_ALREADYINIT, "The external transmission component was already initialized"}, + { ERR_RTP_EXTERNALTRANS_ALREADYWAITING, "The external transmission component is already waiting for incoming data"}, + { ERR_RTP_EXTERNALTRANS_BADRECEIVEMODE, "The external transmission component only supports accepting all incoming packets"}, + { ERR_RTP_EXTERNALTRANS_CANTINITMUTEX, "The external transmitter was unable to initialize a required mutex"}, + { ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS, "Only parameters of type RTPExternalTransmissionParams can be passed to the external transmission component"}, + { ERR_RTP_EXTERNALTRANS_NOACCEPTLIST, "The external transmitter does not have an accept list"}, + { ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED, "The external transmitter does not have a destination list"}, + { ERR_RTP_EXTERNALTRANS_NOIGNORELIST, "The external transmitter does not have an ignore list"}, + { ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT, "The external transmitter does not support the multicast functions"}, + { ERR_RTP_EXTERNALTRANS_NOSENDER, "No sender has been set for this external transmitter"}, + { ERR_RTP_EXTERNALTRANS_NOTCREATED, "The external transmitter has not been created yet"}, + { ERR_RTP_EXTERNALTRANS_NOTINIT, "The external transmitter has not been initialized yet"}, + { ERR_RTP_EXTERNALTRANS_NOTWAITING, "The external transmitter is not currently waiting for incoming data"}, + { ERR_RTP_EXTERNALTRANS_SENDERROR, "The external transmitter was unable to actually send the data"}, + { ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG, "The specified data size exceeds the maximum amount that has been set"}, + { ERR_RTP_UDPV4TRANS_CANTGETSOCKETPORT, "Unable to obtain the existing socket info using 'getsockname'"}, + { ERR_RTP_UDPV4TRANS_NOTANIPV4SOCKET, "The existing socket specified does not appear to be an IPv4 socket"}, + { ERR_RTP_UDPV4TRANS_SOCKETPORTNOTSET, "The existing socket that was specified does not have its port set yet"}, + { ERR_RTP_UDPV4TRANS_CANTGETSOCKETTYPE, "Can't get the socket type of the specified existing socket"}, + { ERR_RTP_UDPV4TRANS_INVALIDSOCKETTYPE, "The specified existing socket is not an UDP socket"}, + { ERR_RTP_UDPV4TRANS_CANTGETVALIDSOCKET, "Can't get a valid socket when trying to choose a port automatically"}, + { ERR_RTP_UDPV4TRANS_TOOMANYATTEMPTSCHOOSINGSOCKET, "Can't seem to get RTP/RTCP ports automatically, too many attempts"}, + { ERR_RTP_RTPSESSION_CHANGEREQUESTEDBUTNOTIMPLEMENTED, "Flag to change data was requested, but OnChangeRTPOrRTCPData was not reimplemented"}, + { ERR_RTP_SECURESESSION_CONTEXTALREADYINITIALIZED, "The initialization function was already called"}, + { ERR_RTP_SECURESESSION_CANTINITIALIZE_SRTPCONTEXT, "Unable to initialize libsrtp context"}, + { ERR_RTP_SECURESESSION_CANTINITMUTEX, "Unable to initialize a mutex" }, + { ERR_RTP_SECURESESSION_CONTEXTNOTINITIALIZED, "The libsrtp context initilization function must be called before it can be used"}, + { ERR_RTP_SECURESESSION_NOTENOUGHDATATOENCRYPT, "There's not enough RTP or RTCP data to encrypt"}, + { ERR_RTP_SECURESESSION_CANTENCRYPTRTPDATA, "Unable to encrypt RTP data"}, + { ERR_RTP_SECURESESSION_CANTENCRYPTRTCPDATA, "Unable to encrypt RTCP data"}, + { ERR_RTP_SECURESESSION_NOTENOUGHDATATODECRYPT, "There's not enough RTP or RTCP data to decrypt"}, + { ERR_RTP_SECURESESSION_CANTDECRYPTRTPDATA, "Unable to decrypt RTP data"}, + { ERR_RTP_SECURESESSION_CANTDECRYPTRTCPDATA, "Unable to decrypt RTCP data"}, + { ERR_RTP_ABORTDESC_ALREADYINIT, "The RTPAbortDescriptors instance is already initialized" }, + { ERR_RTP_ABORTDESC_NOTINIT, "The RTPAbortDescriptors instance is not yet initialized" }, + { ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS, "Unable to create two connected TCP sockets for the abort descriptors" }, + { ERR_RTP_ABORTDESC_CANTCREATEPIPE, "Unable to create a pipe for the abort descriptors" }, + { ERR_RTP_SESSION_THREADSAFETYCONFLICT, "For the background poll thread to be used, thread safety must also be set" }, + { ERR_RTP_SELECT_ERRORINSELECT, "Error in the call to 'select'" }, + { ERR_RTP_SELECT_SOCKETDESCRIPTORTOOLARGE, "A socket descriptor value is too large for a call to 'select' (exceeds FD_SETSIZE)" }, + { ERR_RTP_SELECT_ERRORINPOLL, "Error in the call to 'poll' or 'WSAPoll'" }, + { ERR_RTP_TCPTRANS_NOTINIT, "The TCP transmitter is not yet initialized" }, + { ERR_RTP_TCPTRANS_ALREADYINIT, "The TCP transmitter is already initialized" }, + { ERR_RTP_TCPTRANS_NOTCREATED, "The TCP transmitter is not yet created" }, + { ERR_RTP_TCPTRANS_ALREADYCREATED, "The TCP transmitter is already created" }, + { ERR_RTP_TCPTRANS_ILLEGALPARAMETERS, "The parameters for the TCP transmitter are invalid" }, + { ERR_RTP_TCPTRANS_CANTINITMUTEX, "Unable to initialize a mutex during the initialization of the TCP transmitter" }, + { ERR_RTP_TCPTRANS_ALREADYWAITING, "The TCP transmitter is already waiting for data" }, + { ERR_RTP_TCPTRANS_INVALIDADDRESSTYPE, "The address specified is not a valid address for the TCP transmitter" }, + { ERR_RTP_TCPTRANS_NOSOCKETSPECIFIED, "No socket was specified in the address used for the TCP transmitter" }, + { ERR_RTP_TCPTRANS_NOMULTICASTSUPPORT, "The TCP transmitter does not support multicasting" }, + { ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED, "The TCP transmitter does not support receive modes other than 'accept all'" }, + { ERR_RTP_TCPTRANS_SPECIFIEDSIZETOOBIG, "The maximum packet size for the TCP transmitter is limited to 64KB" }, + { ERR_RTP_TCPTRANS_NOTWAITING, "The TCP transmitter is not waiting for data" }, + { ERR_RTP_TCPTRANS_SOCKETALREADYINDESTINATIONS, "The specified destination address (socket) was already added to the destination list of the TCP transmitter" }, + { ERR_RTP_TCPTRANS_SOCKETNOTFOUNDINDESTINATIONS, "The specified destination address (socket) was not found in the list of destinations of the TCP transmitter" }, + { ERR_RTP_TCPTRANS_ERRORINSEND, "An error occurred in the TCP transmitter while sending a packet" }, + { ERR_RTP_TCPTRANS_ERRORINRECV, "An error occurred in the TCP transmitter while receiving a packet" }, + { 0,0 } +}; + +std::string RTPGetErrorString(int errcode) +{ + int i; + + if (errcode >= 0) + return std::string("No error"); + + i = 0; + while (ErrorDescriptions[i].code != 0) + { + if (ErrorDescriptions[i].code == errcode) + return std::string(ErrorDescriptions[i].description); + i++; + } + + char str[16]; + + RTP_SNPRINTF(str,16,"(%d)",errcode); + + return std::string("Unknown error code") + std::string(str); +} + +} // end namespace + diff --git a/qrtplib/rtperrors.h b/qrtplib/rtperrors.h new file mode 100644 index 000000000..3b9763ee2 --- /dev/null +++ b/qrtplib/rtperrors.h @@ -0,0 +1,253 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 rtperrors.h + */ + +#ifndef RTPERRORS_H + +#define RTPERRORS_H + +//#include "rtpconfig.h" +#include + +namespace qrtplib +{ + +/** Returns a string describing the error code \c errcode. */ +std::string RTPGetErrorString(int errcode); + +} // end namespace + +#define ERR_RTP_OUTOFMEM -1 +#define ERR_RTP_NOTHREADSUPPORT -2 +#define ERR_RTP_COLLISIONLIST_BADADDRESS -3 +#define ERR_RTP_HASHTABLE_ELEMENTALREADYEXISTS -4 +#define ERR_RTP_HASHTABLE_ELEMENTNOTFOUND -5 +#define ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX -6 +#define ERR_RTP_HASHTABLE_NOCURRENTELEMENT -7 +#define ERR_RTP_KEYHASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX -8 +#define ERR_RTP_KEYHASHTABLE_KEYALREADYEXISTS -9 +#define ERR_RTP_KEYHASHTABLE_KEYNOTFOUND -10 +#define ERR_RTP_KEYHASHTABLE_NOCURRENTELEMENT -11 +#define ERR_RTP_PACKBUILD_ALREADYINIT -12 +#define ERR_RTP_PACKBUILD_CSRCALREADYINLIST -13 +#define ERR_RTP_PACKBUILD_CSRCLISTFULL -14 +#define ERR_RTP_PACKBUILD_CSRCNOTINLIST -15 +#define ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET -16 +#define ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET -17 +#define ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET -18 +#define ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE -19 +#define ERR_RTP_PACKBUILD_NOTINIT -20 +#define ERR_RTP_PACKET_BADPAYLOADTYPE -21 +#define ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE -22 +#define ERR_RTP_PACKET_EXTERNALBUFFERNULL -23 +#define ERR_RTP_PACKET_ILLEGALBUFFERSIZE -24 +#define ERR_RTP_PACKET_INVALIDPACKET -25 +#define ERR_RTP_PACKET_TOOMANYCSRCS -26 +#define ERR_RTP_POLLTHREAD_ALREADYRUNNING -27 +#define ERR_RTP_POLLTHREAD_CANTINITMUTEX -28 +#define ERR_RTP_POLLTHREAD_CANTSTARTTHREAD -29 +#define ERR_RTP_RTCPCOMPOUND_INVALIDPACKET -30 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILDING -31 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILT -32 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYGOTREPORT -33 +#define ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG -34 +#define ERR_RTP_RTCPCOMPPACKBUILDER_BUFFERSIZETOOSMALL -35 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALAPPDATALENGTH -36 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALSUBTYPE -37 +#define ERR_RTP_RTCPCOMPPACKBUILDER_INVALIDITEMTYPE -38 +#define ERR_RTP_RTCPCOMPPACKBUILDER_MAXPACKETSIZETOOSMALL -39 +#define ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE -40 +#define ERR_RTP_RTCPCOMPPACKBUILDER_NOREPORTPRESENT -41 +#define ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING -42 +#define ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT -43 +#define ERR_RTP_RTCPCOMPPACKBUILDER_REPORTNOTSTARTED -44 +#define ERR_RTP_RTCPCOMPPACKBUILDER_TOOMANYSSRCS -45 +#define ERR_RTP_RTCPCOMPPACKBUILDER_TOTALITEMLENGTHTOOBIG -46 +#define ERR_RTP_RTCPPACKETBUILDER_ALREADYINIT -47 +#define ERR_RTP_RTCPPACKETBUILDER_ILLEGALMAXPACKSIZE -48 +#define ERR_RTP_RTCPPACKETBUILDER_ILLEGALTIMESTAMPUNIT -49 +#define ERR_RTP_RTCPPACKETBUILDER_NOTINIT -50 +#define ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON -51 +#define ERR_RTP_SCHEDPARAMS_BADFRACTION -52 +#define ERR_RTP_SCHEDPARAMS_BADMINIMUMINTERVAL -53 +#define ERR_RTP_SCHEDPARAMS_INVALIDBANDWIDTH -54 +#define ERR_RTP_SDES_LENGTHTOOBIG -55 +#define ERR_RTP_SDES_MAXPRIVITEMS -56 +#define ERR_RTP_SDES_PREFIXNOTFOUND -57 +#define ERR_RTP_SESSION_ALREADYCREATED -58 +#define ERR_RTP_SESSION_CANTGETLOGINNAME -59 +#define ERR_RTP_SESSION_CANTINITMUTEX -60 +#define ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL -61 +#define ERR_RTP_SESSION_NOTCREATED -62 +#define ERR_RTP_SESSION_UNSUPPORTEDTRANSMISSIONPROTOCOL -63 +#define ERR_RTP_SESSION_USINGPOLLTHREAD -64 +#define ERR_RTP_SOURCES_ALREADYHAVEOWNSSRC -65 +#define ERR_RTP_SOURCES_DONTHAVEOWNSSRC -66 +#define ERR_RTP_SOURCES_ILLEGALSDESTYPE -67 +#define ERR_RTP_SOURCES_SSRCEXISTS -68 +#define ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL -69 +#define ERR_RTP_UDPV4TRANS_ALREADYCREATED -70 +#define ERR_RTP_UDPV4TRANS_ALREADYINIT -71 +#define ERR_RTP_UDPV4TRANS_ALREADYWAITING -72 +#define ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET -73 +#define ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET -74 +#define ERR_RTP_UDPV4TRANS_CANTCREATESOCKET -75 +#define ERR_RTP_UDPV4TRANS_CANTINITMUTEX -76 +#define ERR_RTP_UDPV4TRANS_CANTSETRTCPRECEIVEBUF -77 +#define ERR_RTP_UDPV4TRANS_CANTSETRTCPTRANSMITBUF -78 +#define ERR_RTP_UDPV4TRANS_CANTSETRTPRECEIVEBUF -79 +#define ERR_RTP_UDPV4TRANS_CANTSETRTPTRANSMITBUF -80 +#define ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP -81 +#define ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE -82 +#define ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS -83 +#define ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE -84 +#define ERR_RTP_UDPV4TRANS_NOLOCALIPS -85 +#define ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT -86 +#define ERR_RTP_UDPV4TRANS_NOSUCHENTRY -87 +#define ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS -88 +#define ERR_RTP_UDPV4TRANS_NOTCREATED -89 +#define ERR_RTP_UDPV4TRANS_NOTINIT -90 +#define ERR_RTP_UDPV4TRANS_NOTWAITING -91 +#define ERR_RTP_UDPV4TRANS_PORTBASENOTEVEN -92 +#define ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG -93 +#define ERR_RTP_UDPV6TRANS_ALREADYCREATED -94 +#define ERR_RTP_UDPV6TRANS_ALREADYINIT -95 +#define ERR_RTP_UDPV6TRANS_ALREADYWAITING -96 +#define ERR_RTP_UDPV6TRANS_CANTBINDRTCPSOCKET -97 +#define ERR_RTP_UDPV6TRANS_CANTBINDRTPSOCKET -98 +#define ERR_RTP_UDPV6TRANS_CANTCREATESOCKET -99 +#define ERR_RTP_UDPV6TRANS_CANTINITMUTEX -100 +#define ERR_RTP_UDPV6TRANS_CANTSETRTCPRECEIVEBUF -101 +#define ERR_RTP_UDPV6TRANS_CANTSETRTCPTRANSMITBUF -102 +#define ERR_RTP_UDPV6TRANS_CANTSETRTPRECEIVEBUF -103 +#define ERR_RTP_UDPV6TRANS_CANTSETRTPTRANSMITBUF -104 +#define ERR_RTP_UDPV6TRANS_COULDNTJOINMULTICASTGROUP -105 +#define ERR_RTP_UDPV6TRANS_DIFFERENTRECEIVEMODE -106 +#define ERR_RTP_UDPV6TRANS_ILLEGALPARAMETERS -107 +#define ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE -108 +#define ERR_RTP_UDPV6TRANS_NOLOCALIPS -109 +#define ERR_RTP_UDPV6TRANS_NOMULTICASTSUPPORT -110 +#define ERR_RTP_UDPV6TRANS_NOSUCHENTRY -111 +#define ERR_RTP_UDPV6TRANS_NOTAMULTICASTADDRESS -112 +#define ERR_RTP_UDPV6TRANS_NOTCREATED -113 +#define ERR_RTP_UDPV6TRANS_NOTINIT -114 +#define ERR_RTP_UDPV6TRANS_NOTWAITING -115 +#define ERR_RTP_UDPV6TRANS_PORTBASENOTEVEN -116 +#define ERR_RTP_UDPV6TRANS_SPECIFIEDSIZETOOBIG -117 +#define ERR_RTP_INTERNALSOURCEDATA_INVALIDPROBATIONTYPE -118 +#define ERR_RTP_SESSION_USERDEFINEDTRANSMITTERNULL -119 +#define ERR_RTP_FAKETRANS_ALREADYCREATED -120 +#define ERR_RTP_FAKETRANS_ALREADYINIT -121 +#define ERR_RTP_FAKETRANS_CANTINITMUTEX -122 +#define ERR_RTP_FAKETRANS_COULDNTJOINMULTICASTGROUP -123 +#define ERR_RTP_FAKETRANS_DIFFERENTRECEIVEMODE -124 +#define ERR_RTP_FAKETRANS_ILLEGALPARAMETERS -125 +#define ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE -126 +#define ERR_RTP_FAKETRANS_NOLOCALIPS -127 +#define ERR_RTP_FAKETRANS_NOMULTICASTSUPPORT -128 +#define ERR_RTP_FAKETRANS_NOSUCHENTRY -129 +#define ERR_RTP_FAKETRANS_NOTAMULTICASTADDRESS -130 +#define ERR_RTP_FAKETRANS_NOTCREATED -131 +#define ERR_RTP_FAKETRANS_NOTINIT -132 +#define ERR_RTP_FAKETRANS_PORTBASENOTEVEN -133 +#define ERR_RTP_FAKETRANS_SPECIFIEDSIZETOOBIG -134 +#define ERR_RTP_FAKETRANS_WAITNOTIMPLEMENTED -135 +#define ERR_RTP_RTPRANDOMURANDOM_CANTOPEN -136 +#define ERR_RTP_RTPRANDOMURANDOM_ALREADYOPEN -137 +#define ERR_RTP_RTPRANDOMRANDS_NOTSUPPORTED -138 +#define ERR_RTP_EXTERNALTRANS_ALREADYCREATED -139 +#define ERR_RTP_EXTERNALTRANS_ALREADYINIT -140 +#define ERR_RTP_EXTERNALTRANS_ALREADYWAITING -141 +#define ERR_RTP_EXTERNALTRANS_BADRECEIVEMODE -142 +#define ERR_RTP_EXTERNALTRANS_CANTINITMUTEX -143 +#define ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS -144 +#define ERR_RTP_EXTERNALTRANS_NOACCEPTLIST -145 +#define ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED -146 +#define ERR_RTP_EXTERNALTRANS_NOIGNORELIST -147 +#define ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT -148 +#define ERR_RTP_EXTERNALTRANS_NOSENDER -149 +#define ERR_RTP_EXTERNALTRANS_NOTCREATED -150 +#define ERR_RTP_EXTERNALTRANS_NOTINIT -151 +#define ERR_RTP_EXTERNALTRANS_NOTWAITING -152 +#define ERR_RTP_EXTERNALTRANS_SENDERROR -153 +#define ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG -154 +#define ERR_RTP_UDPV4TRANS_CANTGETSOCKETPORT -155 +#define ERR_RTP_UDPV4TRANS_NOTANIPV4SOCKET -156 +#define ERR_RTP_UDPV4TRANS_SOCKETPORTNOTSET -157 +#define ERR_RTP_UDPV4TRANS_CANTGETSOCKETTYPE -158 +#define ERR_RTP_UDPV4TRANS_INVALIDSOCKETTYPE -159 +#define ERR_RTP_UDPV4TRANS_CANTGETVALIDSOCKET -160 +#define ERR_RTP_UDPV4TRANS_TOOMANYATTEMPTSCHOOSINGSOCKET -161 +#define ERR_RTP_RTPSESSION_CHANGEREQUESTEDBUTNOTIMPLEMENTED -162 +#define ERR_RTP_SECURESESSION_CONTEXTALREADYINITIALIZED -163 +#define ERR_RTP_SECURESESSION_CANTINITIALIZE_SRTPCONTEXT -164 +#define ERR_RTP_SECURESESSION_CANTINITMUTEX -165 +#define ERR_RTP_SECURESESSION_CONTEXTNOTINITIALIZED -166 +#define ERR_RTP_SECURESESSION_NOTENOUGHDATATOENCRYPT -167 +#define ERR_RTP_SECURESESSION_CANTENCRYPTRTPDATA -168 +#define ERR_RTP_SECURESESSION_CANTENCRYPTRTCPDATA -169 +#define ERR_RTP_SECURESESSION_NOTENOUGHDATATODECRYPT -170 +#define ERR_RTP_SECURESESSION_CANTDECRYPTRTPDATA -171 +#define ERR_RTP_SECURESESSION_CANTDECRYPTRTCPDATA -172 +#define ERR_RTP_ABORTDESC_ALREADYINIT -173 +#define ERR_RTP_ABORTDESC_NOTINIT -174 +#define ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS -175 +#define ERR_RTP_ABORTDESC_CANTCREATEPIPE -176 +#define ERR_RTP_SESSION_THREADSAFETYCONFLICT -177 +#define ERR_RTP_SELECT_ERRORINSELECT -178 +#define ERR_RTP_SELECT_SOCKETDESCRIPTORTOOLARGE -179 +#define ERR_RTP_SELECT_ERRORINPOLL -180 +#define ERR_RTP_TCPTRANS_NOTINIT -181 +#define ERR_RTP_TCPTRANS_ALREADYINIT -182 +#define ERR_RTP_TCPTRANS_ALREADYCREATED -183 +#define ERR_RTP_TCPTRANS_ILLEGALPARAMETERS -184 +#define ERR_RTP_TCPTRANS_CANTINITMUTEX -185 +#define ERR_RTP_TCPTRANS_ALREADYWAITING -186 +#define ERR_RTP_TCPTRANS_NOTCREATED -187 +#define ERR_RTP_TCPTRANS_INVALIDADDRESSTYPE -188 +#define ERR_RTP_TCPTRANS_NOSOCKETSPECIFIED -189 +#define ERR_RTP_TCPTRANS_NOMULTICASTSUPPORT -190 +#define ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED -191 +#define ERR_RTP_TCPTRANS_SPECIFIEDSIZETOOBIG -192 +#define ERR_RTP_TCPTRANS_NOTWAITING -193 +#define ERR_RTP_TCPTRANS_SOCKETALREADYINDESTINATIONS -194 +#define ERR_RTP_TCPTRANS_SOCKETNOTFOUNDINDESTINATIONS -195 +#define ERR_RTP_TCPTRANS_ERRORINSEND -196 +#define ERR_RTP_TCPTRANS_ERRORINRECV -197 + +#endif // RTPERRORS_H + diff --git a/qrtplib/rtpinternalutils.h b/qrtplib/rtpinternalutils.h new file mode 100644 index 000000000..503401bf2 --- /dev/null +++ b/qrtplib/rtpinternalutils.h @@ -0,0 +1,61 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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. + +*/ + +#ifndef RTPINTERNALUTILS_H + +#define RTPINTERNALUTILS_H + +//#include "rtpconfig.h" + +#if defined(RTP_HAVE_SNPRINTF_S) + #include + #include + #define RTP_SNPRINTF _snprintf_s +#elif defined(RTP_HAVE_SNPRINTF) + #include + #include + #define RTP_SNPRINTF _snprintf +#else + #include + #define RTP_SNPRINTF snprintf +#endif + +#ifdef RTP_HAVE_STRNCPY_S + #define RTP_STRNCPY(dest, src, len) strncpy_s((dest), (len), (src), _TRUNCATE) +#else + #define RTP_STRNCPY(dest, src, len) strncpy((dest), (src), (len)) +#endif // RTP_HAVE_STRNCPY_S + +#endif // RTPINTERNALUTILS_H + diff --git a/qrtplib/rtppacketbuilder.cpp b/qrtplib/rtppacketbuilder.cpp new file mode 100644 index 000000000..bc91c3583 --- /dev/null +++ b/qrtplib/rtppacketbuilder.cpp @@ -0,0 +1,286 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 "rtppacketbuilder.h" +#include "rtperrors.h" +#include "rtppacket.h" +#include "rtpsources.h" +#include +#include +//#include "rtpdebug.h" + +namespace qrtplib +{ + +RTPPacketBuilder::RTPPacketBuilder(RTPRandom &r) : rtprnd(r), lastwallclocktime(0,0) +{ + init = false; +} + +RTPPacketBuilder::~RTPPacketBuilder() +{ + Destroy(); +} + +int RTPPacketBuilder::Init(std::size_t max) +{ + if (init) { + return ERR_RTP_PACKBUILD_ALREADYINIT; + } + + if (max <= 0) { + return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE; + } + + maxpacksize = max; + buffer = new uint8_t[max]; + if (buffer == 0) { + return ERR_RTP_OUTOFMEM; + } + packetlength = 0; + + CreateNewSSRC(); + + deftsset = false; + defptset = false; + defmarkset = false; + + numcsrcs = 0; + + init = true; + return 0; +} + +void RTPPacketBuilder::Destroy() +{ + if (!init) { + return; + } + delete[] buffer; + init = false; +} + +int RTPPacketBuilder::SetMaximumPacketSize(std::size_t max) +{ + uint8_t *newbuf; + + if (max <= 0) { + return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE; + } + newbuf = new uint8_t[max]; + if (newbuf == 0) { + return ERR_RTP_OUTOFMEM; + } + + delete[] buffer; + buffer = newbuf; + maxpacksize = max; + return 0; +} + +int RTPPacketBuilder::AddCSRC(uint32_t csrc) +{ + if (!init) { + return ERR_RTP_PACKBUILD_NOTINIT; + } + if (numcsrcs >= RTP_MAXCSRCS) { + return ERR_RTP_PACKBUILD_CSRCLISTFULL; + } + + int i; + + for (i = 0; i < numcsrcs; i++) { + if (csrcs[i] == csrc) { + return ERR_RTP_PACKBUILD_CSRCALREADYINLIST; + } + } + csrcs[numcsrcs] = csrc; + numcsrcs++; + return 0; +} + +int RTPPacketBuilder::DeleteCSRC(uint32_t csrc) +{ + if (!init) { + return ERR_RTP_PACKBUILD_NOTINIT; + } + + int i = 0; + bool found = false; + + while (!found && i < numcsrcs) + { + if (csrcs[i] == csrc) { + found = true; + } else { + i++; + } + } + + if (!found) { + return ERR_RTP_PACKBUILD_CSRCNOTINLIST; + } + + // move the last csrc in the place of the deleted one + numcsrcs--; + if (numcsrcs > 0 && numcsrcs != i) { + csrcs[i] = csrcs[numcsrcs]; + } + + return 0; +} + +void RTPPacketBuilder::ClearCSRCList() +{ + if (!init) { + return; + } + numcsrcs = 0; +} + +uint32_t RTPPacketBuilder::CreateNewSSRC() +{ + ssrc = rtprnd.GetRandom32(); + timestamp = rtprnd.GetRandom32(); + seqnr = rtprnd.GetRandom16(); + + // p 38: the count SHOULD be reset if the sender changes its SSRC identifier + numpayloadbytes = 0; + numpackets = 0; + return ssrc; +} + +uint32_t RTPPacketBuilder::CreateNewSSRC(RTPSources &sources) +{ + bool found; + + do + { + ssrc = rtprnd.GetRandom32(); + found = sources.GotEntry(ssrc); + } while (found); + + timestamp = rtprnd.GetRandom32(); + seqnr = rtprnd.GetRandom16(); + + // p 38: the count SHOULD be reset if the sender changes its SSRC identifier + numpayloadbytes = 0; + numpackets = 0; + return ssrc; +} + +int RTPPacketBuilder::BuildPacket(const void *data, std::size_t len) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + if (!defptset) + return ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET; + if (!defmarkset) + return ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET; + if (!deftsset) + return ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET; + return PrivateBuildPacket(data,len,defaultpayloadtype,defaultmark,defaulttimestampinc,false); +} + +int RTPPacketBuilder::BuildPacket(const void *data, std::size_t len, + uint8_t pt,bool mark,uint32_t timestampinc) +{ + if (!init) { + return ERR_RTP_PACKBUILD_NOTINIT; + } + + return PrivateBuildPacket(data,len,pt,mark,timestampinc,false); +} + +int RTPPacketBuilder::BuildPacketEx(const void *data, std::size_t len, + uint16_t hdrextID, const void *hdrextdata, std::size_t numhdrextwords) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + if (!defptset) + return ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET; + if (!defmarkset) + return ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET; + if (!deftsset) + return ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET; + return PrivateBuildPacket(data,len,defaultpayloadtype,defaultmark,defaulttimestampinc,true,hdrextID,hdrextdata,numhdrextwords); +} + +int RTPPacketBuilder::BuildPacketEx(const void *data, std::size_t len, + uint8_t pt, bool mark, uint32_t timestampinc, + uint16_t hdrextID, const void *hdrextdata, std::size_t numhdrextwords) +{ + if (!init) { + return ERR_RTP_PACKBUILD_NOTINIT; + } + return PrivateBuildPacket(data,len,pt,mark,timestampinc,true,hdrextID,hdrextdata,numhdrextwords); + +} + +int RTPPacketBuilder::PrivateBuildPacket(const void *data, std::size_t len, + uint8_t pt, bool mark, uint32_t timestampinc, bool gotextension, + uint16_t hdrextID, const void *hdrextdata, std::size_t numhdrextwords) +{ + RTPPacket p(pt,data,len,seqnr,timestamp,ssrc,mark,numcsrcs,csrcs,gotextension,hdrextID, + (uint16_t)numhdrextwords,hdrextdata,buffer,maxpacksize,GetMemoryManager()); + int status = p.GetCreationError(); + + if (status < 0) { + return status + }; + packetlength = p.GetPacketLength(); + + if (numpackets == 0) // first packet + { + lastwallclocktime = RTPTime::CurrentTime(); + lastrtptimestamp = timestamp; + prevrtptimestamp = timestamp; + } + else if (timestamp != prevrtptimestamp) + { + lastwallclocktime = RTPTime::CurrentTime(); + lastrtptimestamp = timestamp; + prevrtptimestamp = timestamp; + } + + numpayloadbytes += (uint32_t)p.GetPayloadLength(); + numpackets++; + timestamp += timestampinc; + seqnr++; + + return 0; +} + +} // end namespace + diff --git a/qrtplib/rtppacketbuilder.h b/qrtplib/rtppacketbuilder.h new file mode 100644 index 000000000..e0e30ba52 --- /dev/null +++ b/qrtplib/rtppacketbuilder.h @@ -0,0 +1,275 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 rtppacketbuilder.h + */ + +#ifndef RTPPACKETBUILDER_H + +#define RTPPACKETBUILDER_H + +//#include "rtpconfig.h" +#include "rtperrors.h" +#include "rtpdefines.h" +#include "rtprandom.h" +#include "rtptimeutilities.h" +//#include "rtptypes.h" + +namespace qrtplib +{ + +class RTPSources; + +/** This class can be used to build RTP packets and is a bit more high-level than the RTPPacket + * class: it generates an SSRC identifier, keeps track of timestamp and sequence number etc. + */ +class RTPPacketBuilder +{ +public: + /** Constructs an instance which will use \c rtprand for generating random numbers + * (used to initialize the SSRC value and sequence number), optionally installing a memory manager. + **/ + RTPPacketBuilder(RTPRandom &rtprand); + ~RTPPacketBuilder(); + + /** Initializes the builder to only allow packets with a size below \c maxpacksize. */ + int Init(std::size_t maxpacksize); + + /** Cleans up the builder. */ + void Destroy(); + + /** Returns the number of packets which have been created with the current SSRC identifier. */ + uint32_t GetPacketCount() { if (!init) return 0; return numpackets; } + + /** Returns the number of payload octets which have been generated with this SSRC identifier. */ + uint32_t GetPayloadOctetCount() { if (!init) return 0; return numpayloadbytes; } + + /** Sets the maximum allowed packet size to \c maxpacksize. */ + int SetMaximumPacketSize(std::size_t maxpacksize); + + /** Adds a CSRC to the CSRC list which will be stored in the RTP packets. */ + int AddCSRC(uint32_t csrc); + + /** Deletes a CSRC from the list which will be stored in the RTP packets. */ + int DeleteCSRC(uint32_t csrc); + + /** Clears the CSRC list. */ + void ClearCSRCList(); + + /** Builds a packet with payload \c data and payload length \c len. + * Builds a packet with payload \c data and payload length \c len. The payload type, marker + * and timestamp increment used will be those that have been set using the \c SetDefault + * functions below. + */ + int BuildPacket(const void *data, std::size_t len); + + /** Builds a packet with payload \c data and payload length \c len. + * Builds a packet with payload \c data and payload length \c len. The payload type will be + * set to \c pt, the marker bit to \c mark and after building this packet, the timestamp will + * be incremented with \c timestamp. + */ + int BuildPacket(const void *data, std::size_t len, + uint8_t pt, bool mark, uint32_t timestampinc); + + /** Builds a packet with payload \c data and payload length \c len. + * Builds a packet with payload \c data and payload length \c len. The payload type, marker + * and timestamp increment used will be those that have been set using the \c SetDefault + * functions below. This packet will also contain an RTP header extension with identifier + * \c hdrextID and data \c hdrextdata. The length of the header extension data is given by + * \c numhdrextwords which expresses the length in a number of 32-bit words. + */ + int BuildPacketEx(const void *data, std::size_t len, + uint16_t hdrextID, const void *hdrextdata, std::size_t numhdrextwords); + + /** Builds a packet with payload \c data and payload length \c len. + * Builds a packet with payload \c data and payload length \c len. The payload type will be set + * to \c pt, the marker bit to \c mark and after building this packet, the timestamp will + * be incremented with \c timestamp. This packet will also contain an RTP header extension + * with identifier \c hdrextID and data \c hdrextdata. The length of the header extension + * data is given by \c numhdrextwords which expresses the length in a number of 32-bit words. + */ + int BuildPacketEx(const void *data, std::size_t len, + uint8_t pt, bool mark, uint32_t timestampinc, + uint16_t hdrextID, const void *hdrextdata, std::size_t numhdrextwords); + + /** Returns a pointer to the last built RTP packet data. */ + uint8_t *GetPacket() { if (!init) return 0; return buffer; } + + /** Returns the size of the last built RTP packet. */ + size_t GetPacketLength() { if (!init) return 0; return packetlength; } + + /** Sets the default payload type to \c pt. */ + int SetDefaultPayloadType(uint8_t pt); + + /** Sets the default marker bit to \c m. */ + int SetDefaultMark(bool m); + + /** Sets the default timestamp increment to \c timestampinc. */ + int SetDefaultTimestampIncrement(uint32_t timestampinc); + + /** This function increments the timestamp with the amount given by \c inc. + * This function increments the timestamp with the amount given by \c inc. This can be useful + * if, for example, a packet was not sent because it contained only silence. Then, this function + * should be called to increment the timestamp with the appropriate amount so that the next packets + * will still be played at the correct time at other hosts. + */ + int IncrementTimestamp(uint32_t inc); + + /** This function increments the timestamp with the amount given set by the SetDefaultTimestampIncrement + * member function. + * This function increments the timestamp with the amount given set by the SetDefaultTimestampIncrement + * member function. This can be useful if, for example, a packet was not sent because it contained only silence. + * Then, this function should be called to increment the timestamp with the appropriate amount so that the next + * packets will still be played at the correct time at other hosts. + */ + int IncrementTimestampDefault(); + + /** Creates a new SSRC to be used in generated packets. + * Creates a new SSRC to be used in generated packets. This will also generate new timestamp and + * sequence number offsets. + */ + uint32_t CreateNewSSRC(); + + /** Creates a new SSRC to be used in generated packets. + * Creates a new SSRC to be used in generated packets. This will also generate new timestamp and + * sequence number offsets. The source table \c sources is used to make sure that the chosen SSRC + * isn't used by another participant yet. + */ + uint32_t CreateNewSSRC(RTPSources &sources); + + /** Returns the current SSRC identifier. */ + uint32_t GetSSRC() const { if (!init) return 0; return ssrc; } + + /** Returns the current RTP timestamp. */ + uint32_t GetTimestamp() const { if (!init) return 0; return timestamp; } + + /** Returns the current sequence number. */ + uint16_t GetSequenceNumber() const { if (!init) return 0; return seqnr; } + + /** Returns the time at which a packet was generated. + * Returns the time at which a packet was generated. This is not necessarily the time at which + * the last RTP packet was generated: if the timestamp increment was zero, the time is not updated. + */ + RTPTime GetPacketTime() const { if (!init) return RTPTime(0,0); return lastwallclocktime; } + + /** Returns the RTP timestamp which corresponds to the time returned by the previous function. */ + uint32_t GetPacketTimestamp() const { if (!init) return 0; return lastrtptimestamp; } + + /** Sets a specific SSRC to be used. + * Sets a specific SSRC to be used. Does not create a new timestamp offset or sequence number + * offset. Does not reset the packet count or byte count. Think twice before using this! + */ + void AdjustSSRC(uint32_t s) { ssrc = s; } +private: + int PrivateBuildPacket(const void *data, std::size_t len, + uint8_t pt, bool mark, uint32_t timestampinc, bool gotextension, + uint16_t hdrextID = 0, const void *hdrextdata = 0, std::size_t numhdrextwords = 0); + + RTPRandom &rtprnd; + std::size_t maxpacksize; + uint8_t *buffer; + std::size_t packetlength; + + uint32_t numpayloadbytes; + uint32_t numpackets; + bool init; + + uint32_t ssrc; + uint32_t timestamp; + uint16_t seqnr; + + uint32_t defaulttimestampinc; + uint8_t defaultpayloadtype; + bool defaultmark; + + bool deftsset,defptset,defmarkset; + + uint32_t csrcs[RTP_MAXCSRCS]; + int numcsrcs; + + RTPTime lastwallclocktime; + uint32_t lastrtptimestamp; + uint32_t prevrtptimestamp; +}; + +inline int RTPPacketBuilder::SetDefaultPayloadType(uint8_t pt) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + defptset = true; + defaultpayloadtype = pt; + return 0; +} + +inline int RTPPacketBuilder::SetDefaultMark(bool m) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + defmarkset = true; + defaultmark = m; + return 0; +} + +inline int RTPPacketBuilder::SetDefaultTimestampIncrement(uint32_t timestampinc) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + deftsset = true; + defaulttimestampinc = timestampinc; + return 0; +} + +inline int RTPPacketBuilder::IncrementTimestamp(uint32_t inc) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + timestamp += inc; + return 0; +} + +inline int RTPPacketBuilder::IncrementTimestampDefault() +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + if (!deftsset) + return ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET; + timestamp += defaulttimestampinc; + return 0; +} + +} // end namespace + +#endif // RTPPACKETBUILDER_H + diff --git a/qrtplib/rtprandom.cpp b/qrtplib/rtprandom.cpp new file mode 100644 index 000000000..56b3bd165 --- /dev/null +++ b/qrtplib/rtprandom.cpp @@ -0,0 +1,90 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 "rtprandom.h" +#include "rtprandomurandom.h" +#include "rtprandomrand48.h" +#include +#ifndef WIN32 + #include +#else + #include + #include +#endif // WIN32 + +//#include "rtpdebug.h" + +namespace qrtplib +{ + +uint32_t RTPRandom::PickSeed() +{ + uint32_t x; +// TODO: do it for MinGW see sdrbase/util/uid.h,cpp +#if defined(WIN32) + x = (uint32_t)GetCurrentProcessId(); + + FILETIME ft; + SYSTEMTIME st; + + GetSystemTime(&st); + SystemTimeToFileTime(&st,&ft); + + x += ft.dwLowDateTime; + x ^= (uint32_t)((uint8_t *)this - (uint8_t *)0); +#else + x = (uint32_t)getpid(); + x += (uint32_t)time(0); + x += (uint32_t)clock(); + x ^= (uint32_t)((uint8_t *)this - (uint8_t *)0); +#endif + return x; +} + +RTPRandom *RTPRandom::CreateDefaultRandomNumberGenerator() +{ + RTPRandomURandom *r = new RTPRandomURandom(); + RTPRandom *rRet = r; + + if (r->Init() < 0) // fall back to rand48 + { + delete r; + rRet = new RTPRandomRand48(); + } + + return rRet; +} + +} // end namespace + diff --git a/qrtplib/rtprandom.h b/qrtplib/rtprandom.h new file mode 100644 index 000000000..e8316366b --- /dev/null +++ b/qrtplib/rtprandom.h @@ -0,0 +1,82 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 rtprandom.h + */ + +#ifndef RTPRANDOM_H + +#define RTPRANDOM_H + +//#include "rtpconfig.h" +//#include "rtptypes.h" +#include +#include + +#define RTPRANDOM_2POWMIN63 1.08420217248550443400745280086994171142578125e-19 + +namespace qrtplib +{ + +/** Interface for generating random numbers. */ +class RTPRandom +{ +public: + RTPRandom() { } + virtual ~RTPRandom() { } + + /** Returns a random eight bit value. */ + virtual uint8_t GetRandom8() = 0; + + /** Returns a random sixteen bit value. */ + virtual uint16_t GetRandom16() = 0; + + /** Returns a random thirty-two bit value. */ + virtual uint32_t GetRandom32() = 0; + + /** Returns a random number between $0.0$ and $1.0$. */ + virtual double GetRandomDouble() = 0; + + /** Can be used by subclasses to generate a seed for a random number generator. */ + uint32_t PickSeed(); + + /** Allocate a default random number generator based on your platform. */ + static RTPRandom *CreateDefaultRandomNumberGenerator(); +}; + +} // end namespace + +#endif // RTPRANDOM_H + diff --git a/qrtplib/rtprandomrand48.cpp b/qrtplib/rtprandomrand48.cpp new file mode 100644 index 000000000..d14bed196 --- /dev/null +++ b/qrtplib/rtprandomrand48.cpp @@ -0,0 +1,89 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 "rtprandomrand48.h" + +namespace qrtplib +{ + +RTPRandomRand48::RTPRandomRand48() +{ + SetSeed(PickSeed()); +} + +RTPRandomRand48::RTPRandomRand48(uint32_t seed) +{ + SetSeed(seed); +} + +RTPRandomRand48::~RTPRandomRand48() +{ +} + +void RTPRandomRand48::SetSeed(uint32_t seed) +{ + state = ((uint64_t)seed) << 16 | 0x330EULL; +} + +uint8_t RTPRandomRand48::GetRandom8() +{ + uint32_t x = ((GetRandom32() >> 24)&0xff); + + return (uint8_t)x; +} + +uint16_t RTPRandomRand48::GetRandom16() +{ + uint32_t x = ((GetRandom32() >> 16)&0xffff); + + return (uint16_t)x; +} + +uint32_t RTPRandomRand48::GetRandom32() +{ + state = ((0x5DEECE66DULL*state) + 0xBULL)&0x0000ffffffffffffULL; + uint32_t x = (uint32_t)((state>>16)&0xffffffffULL); + return x; +} + +double RTPRandomRand48::GetRandomDouble() +{ + state = ((0x5DEECE66DULL*state) + 0xBULL)&0x0000ffffffffffffULL; + int64_t x = (int64_t)state; + double y = 3.552713678800500929355621337890625e-15 * (double)x; + return y; +} + +} // end namespace + diff --git a/qrtplib/rtprandomrand48.h b/qrtplib/rtprandomrand48.h new file mode 100644 index 000000000..10b36a7e1 --- /dev/null +++ b/qrtplib/rtprandomrand48.h @@ -0,0 +1,71 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 rtprandomrand48.h + */ + +#ifndef RTPRANDOMRAND48_H + +#define RTPRANDOMRAND48_H + +//#include "rtpconfig.h" +#include "rtprandom.h" +#include +#include + +namespace qrtplib +{ + +/** A random number generator using the algorithm of the rand48 set of functions. */ +class RTPRandomRand48 : public RTPRandom +{ +public: + RTPRandomRand48(); + RTPRandomRand48(uint32_t seed); + ~RTPRandomRand48(); + + uint8_t GetRandom8(); + uint16_t GetRandom16(); + uint32_t GetRandom32(); + double GetRandomDouble(); +private: + void SetSeed(uint32_t seed); + uint64_t state; +}; + +} // end namespace + +#endif // RTPRANDOMRAND48_H + diff --git a/qrtplib/rtprandomurandom.cpp b/qrtplib/rtprandomurandom.cpp new file mode 100644 index 000000000..6e831e40e --- /dev/null +++ b/qrtplib/rtprandomurandom.cpp @@ -0,0 +1,121 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 "rtprandomurandom.h" +#include "rtperrors.h" + +//#include "rtpdebug.h" + +namespace qrtplib +{ + +RTPRandomURandom::RTPRandomURandom() +{ + device = 0; +} + +RTPRandomURandom::~RTPRandomURandom() +{ + if (device) + fclose(device); +} + +int RTPRandomURandom::Init() +{ + if (device) + return ERR_RTP_RTPRANDOMURANDOM_ALREADYOPEN; + + device = fopen("/dev/urandom","rb"); + if (device == 0) + return ERR_RTP_RTPRANDOMURANDOM_CANTOPEN; + + return 0; +} + +uint8_t RTPRandomURandom::GetRandom8() +{ + if (!device) + return 0; + + uint8_t value; + + fread(&value, sizeof(uint8_t), 1, device); + + return value; +} + +uint16_t RTPRandomURandom::GetRandom16() +{ + if (!device) + return 0; + + uint16_t value; + + fread(&value, sizeof(uint16_t), 1, device); + + return value; +} + +uint32_t RTPRandomURandom::GetRandom32() +{ + if (!device) + return 0; + + uint32_t value; + + fread(&value, sizeof(uint32_t), 1, device); + + return value; +} + +double RTPRandomURandom::GetRandomDouble() +{ + if (!device) + return 0; + + uint64_t value; + + fread(&value, sizeof(uint64_t), 1, device); + + value &= 0x7fffffffffffffffULL; + + int64_t value2 = (int64_t)value; + double x = RTPRANDOM_2POWMIN63*(double)value2; + + return x; + +} + +} // end namespace + diff --git a/qrtplib/rtprandomurandom.h b/qrtplib/rtprandomurandom.h new file mode 100644 index 000000000..160820a94 --- /dev/null +++ b/qrtplib/rtprandomurandom.h @@ -0,0 +1,70 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 rtprandomurandom.h + */ + +#ifndef RTPRANDOMURANDOM_H + +#define RTPRANDOMURANDOM_H + +//#include "rtpconfig.h" +#include "rtprandom.h" +#include + +namespace qrtplib +{ + +/** A random number generator which uses bytes delivered by the /dev/urandom device. */ +class RTPRandomURandom : public RTPRandom +{ +public: + RTPRandomURandom(); + ~RTPRandomURandom(); + + /** Initialize the random number generator. */ + int Init(); + + uint8_t GetRandom8(); + uint16_t GetRandom16(); + uint32_t GetRandom32(); + double GetRandomDouble(); +private: + FILE *device; +}; + +} // end namespace + +#endif // RTPRANDOMURANDOM_H diff --git a/qrtplib/rtptimeutilities.cpp b/qrtplib/rtptimeutilities.cpp new file mode 100644 index 000000000..9554d57fd --- /dev/null +++ b/qrtplib/rtptimeutilities.cpp @@ -0,0 +1,46 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 "rtpconfig.h" +#include "rtptimeutilities.h" + +namespace jrtplib +{ + +RTPTimeInitializerObject::RTPTimeInitializerObject() +{ + dummy = -1; +} + +} // end namespace diff --git a/qrtplib/rtptimeutilities.h b/qrtplib/rtptimeutilities.h new file mode 100644 index 000000000..9c1078efa --- /dev/null +++ b/qrtplib/rtptimeutilities.h @@ -0,0 +1,323 @@ +/* + Rewritten to fit into the Qt Network framework + Copyright (c) 2018 Edouard Griffiths, F4EXB + + 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 rtptimeutilities.h + */ + +#ifndef RTPTIMEUTILITIES_H + +#define RTPTIMEUTILITIES_H + +//#include "rtpconfig.h" +//#include "rtptypes.h" +#include +#include +#include +#include + +#define RTP_NTPTIMEOFFSET 2208988800UL +#define C1000000 1000000ULL +#define CEPOCH 11644473600000000ULL + +namespace jrtplib +{ + +/** + * This is a simple wrapper for the most significant word (MSW) and least + * significant word (LSW) of an NTP timestamp. + */ +class RTPNTPTime +{ +public: + /** This constructor creates and instance with MSW \c m and LSW \c l. */ + RTPNTPTime(uint32_t m, uint32_t l) { msw = m ; lsw = l; } + + /** Returns the most significant word. */ + uint32_t GetMSW() const { return msw; } + + /** Returns the least significant word. */ + uint32_t GetLSW() const { return lsw; } +private: + uint32_t msw,lsw; +}; + +/** This class is used to specify wallclock time, delay intervals etc. + * This class is used to specify wallclock time, delay intervals etc. + * It stores a number of seconds and a number of microseconds. + */ +class RTPTime +{ +public: + /** Returns an RTPTime instance representing the current wallclock time. + * Returns an RTPTime instance representing the current wallclock time. This is expressed + * as a number of seconds since 00:00:00 UTC, January 1, 1970. + */ + static RTPTime CurrentTime(); + + /** This function waits the amount of time specified in \c delay. */ + static void Wait(const RTPTime &delay); + + /** Creates an RTPTime instance representing \c t, which is expressed in units of seconds. */ + RTPTime(double t); + + /** Creates an instance that corresponds to \c ntptime. + * Creates an instance that corresponds to \c ntptime. If + * the conversion cannot be made, both the seconds and the + * microseconds are set to zero. + */ + RTPTime(RTPNTPTime ntptime); + + /** Creates an instance corresponding to \c seconds and \c microseconds. */ + RTPTime(int64_t seconds, uint32_t microseconds); + + /** Returns the number of seconds stored in this instance. */ + int64_t GetSeconds() const; + + /** Returns the number of microseconds stored in this instance. */ + uint32_t GetMicroSeconds() const; + + /** Returns the time stored in this instance, expressed in units of seconds. */ + double GetDouble() const { return m_t; } + + /** Returns the NTP time corresponding to the time stored in this instance. */ + RTPNTPTime GetNTPTime() const; + + RTPTime &operator-=(const RTPTime &t); + RTPTime &operator+=(const RTPTime &t); + bool operator<(const RTPTime &t) const; + bool operator>(const RTPTime &t) const; + bool operator<=(const RTPTime &t) const; + bool operator>=(const RTPTime &t) const; + + bool IsZero() const { return m_t == 0; } +private: + double m_t; +}; + +inline RTPTime::RTPTime(double t) +{ + m_t = t; +} + +inline RTPTime::RTPTime(int64_t seconds, uint32_t microseconds) +{ + if (seconds >= 0) + { + m_t = (double)seconds + 1e-6*(double)microseconds; + } + else + { + int64_t possec = -seconds; + + m_t = (double)possec + 1e-6*(double)microseconds; + m_t = -m_t; + } +} + +inline RTPTime::RTPTime(RTPNTPTime ntptime) +{ + if (ntptime.GetMSW() < RTP_NTPTIMEOFFSET) + { + m_t = 0; + } + else + { + uint32_t sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET; + + double x = (double)ntptime.GetLSW(); + x /= (65536.0*65536.0); + x *= 1000000.0; + uint32_t microsec = (uint32_t)x; + + m_t = (double)sec + 1e-6*(double)microsec; + } +} + +inline int64_t RTPTime::GetSeconds() const +{ + return (int64_t)m_t; +} + +inline uint32_t RTPTime::GetMicroSeconds() const +{ + uint32_t microsec; + + if (m_t >= 0) + { + int64_t sec = (int64_t)m_t; + microsec = (uint32_t)(1e6*(m_t - (double)sec) + 0.5); + } + else // m_t < 0 + { + int64_t sec = (int64_t)(-m_t); + microsec = (uint32_t)(1e6*((-m_t) - (double)sec) + 0.5); + } + + if (microsec >= 1000000) + return 999999; + // Unsigned, it can never be less than 0 + // if (microsec < 0) + // return 0; + return microsec; +} + +#ifdef RTP_HAVE_CLOCK_GETTIME +inline double RTPTime_timespecToDouble(struct timespec &ts) +{ + return (double)ts.tv_sec + 1e-9*(double)ts.tv_nsec; +} + +inline RTPTime RTPTime::CurrentTime() +{ + static bool s_initialized = false; + static double s_startOffet = 0; + + if (!s_initialized) + { + s_initialized = true; + + // Get the corresponding times in system time and monotonic time + struct timespec tpSys, tpMono; + + clock_gettime(CLOCK_REALTIME, &tpSys); + clock_gettime(CLOCK_MONOTONIC, &tpMono); + + double tSys = RTPTime_timespecToDouble(tpSys); + double tMono = RTPTime_timespecToDouble(tpMono); + + s_startOffet = tSys - tMono; + return tSys; + } + + struct timespec tpMono; + clock_gettime(CLOCK_MONOTONIC, &tpMono); + + double tMono0 = RTPTime_timespecToDouble(tpMono); + return tMono0 + s_startOffet; +} + +#else // gettimeofday fallback + +inline RTPTime RTPTime::CurrentTime() +{ + struct timeval tv; + + gettimeofday(&tv,0); + return RTPTime((uint64_t)tv.tv_sec,(uint32_t)tv.tv_usec); +} +#endif // RTP_HAVE_CLOCK_GETTIME + +inline void RTPTime::Wait(const RTPTime &delay) +{ + if (delay.m_t <= 0) + return; + + uint64_t sec = (uint64_t)delay.m_t; + uint64_t nanosec = (uint32_t)(1e9*(delay.m_t-(double)sec)); + + struct timespec req,rem; + int ret; + + req.tv_sec = (time_t)sec; + req.tv_nsec = ((long)nanosec); + do + { + ret = nanosleep(&req,&rem); + req = rem; + } while (ret == -1 && errno == EINTR); +} + +inline RTPTime &RTPTime::operator-=(const RTPTime &t) +{ + m_t -= t.m_t; + return *this; +} + +inline RTPTime &RTPTime::operator+=(const RTPTime &t) +{ + m_t += t.m_t; + return *this; +} + +inline RTPNTPTime RTPTime::GetNTPTime() const +{ + uint32_t sec = (uint32_t)m_t; + uint32_t microsec = (uint32_t)((m_t - (double)sec)*1e6); + + uint32_t msw = sec+RTP_NTPTIMEOFFSET; + uint32_t lsw; + double x; + + x = microsec/1000000.0; + x *= (65536.0*65536.0); + lsw = (uint32_t)x; + + return RTPNTPTime(msw,lsw); +} + +inline bool RTPTime::operator<(const RTPTime &t) const +{ + return m_t < t.m_t; +} + +inline bool RTPTime::operator>(const RTPTime &t) const +{ + return m_t > t.m_t; +} + +inline bool RTPTime::operator<=(const RTPTime &t) const +{ + return m_t <= t.m_t; +} + +inline bool RTPTime::operator>=(const RTPTime &t) const +{ + return m_t >= t.m_t; +} + +class RTPTimeInitializerObject +{ +public: + RTPTimeInitializerObject(); + void Dummy() { dummy++; } +private: + int dummy; +}; + +} // end namespace + + +#endif // RTPTIMEUTILITIES_H +