mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 21:20:31 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			387 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			387 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 | 
						|
 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 rtcpsdespacket.h
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef RTCPSDESPACKET_H
 | 
						|
 | 
						|
#define RTCPSDESPACKET_H
 | 
						|
 | 
						|
#include "rtpconfig.h"
 | 
						|
#include "rtcppacket.h"
 | 
						|
#include "rtpstructs.h"
 | 
						|
#include "rtpdefines.h"
 | 
						|
#include "rtpendian.h"
 | 
						|
 | 
						|
#include "export.h"
 | 
						|
 | 
						|
namespace qrtplib
 | 
						|
{
 | 
						|
 | 
						|
class RTCPCompoundPacket;
 | 
						|
 | 
						|
/** Describes an RTCP source description packet. */
 | 
						|
class QRTPLIB_API RTCPSDESPacket: public RTCPPacket
 | 
						|
{
 | 
						|
public:
 | 
						|
    /** Identifies the type of an SDES item. */
 | 
						|
    enum ItemType
 | 
						|
    {
 | 
						|
        None, /**< Used when the iteration over the items has finished. */
 | 
						|
        CNAME, /**< Used for a CNAME (canonical name) item. */
 | 
						|
        NAME, /**< Used for a NAME item. */
 | 
						|
        EMAIL, /**< Used for an EMAIL item. */
 | 
						|
        PHONE, /**< Used for a PHONE item. */
 | 
						|
        LOC, /**< Used for a LOC (location) item. */
 | 
						|
        TOOL, /**< Used for a TOOL item. */
 | 
						|
        NOTE, /**< Used for a NOTE item. */
 | 
						|
        PRIV, /**< Used for a PRIV item. */
 | 
						|
        Unknown /**< Used when there is an item present, but the type is not recognized. */
 | 
						|
    };
 | 
						|
 | 
						|
    /** Creates an instance based on the data in \c data with length \c datalen.
 | 
						|
     *  Creates an instance based on the data in \c data with length \c datalen. Since the \c data pointer
 | 
						|
     *  is referenced inside the class (no copy of the data is made) one must make sure that the memory it
 | 
						|
     *  points to is valid as long as the class instance exists.
 | 
						|
     */
 | 
						|
    RTCPSDESPacket(uint8_t *data, std::size_t datalen);
 | 
						|
    ~RTCPSDESPacket()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /** Returns the number of SDES chunks in the SDES packet.
 | 
						|
     *  Returns the number of SDES chunks in the SDES packet. Each chunk has its own SSRC identifier.
 | 
						|
     */
 | 
						|
    int GetChunkCount() const;
 | 
						|
 | 
						|
    /** Starts the iteration over the chunks.
 | 
						|
     *  Starts the iteration. If no SDES chunks are present, the function returns \c false. Otherwise,
 | 
						|
     *  it returns \c true and sets the current chunk to be the first chunk.
 | 
						|
     */
 | 
						|
    bool GotoFirstChunk();
 | 
						|
 | 
						|
    /** Sets the current chunk to the next available chunk.
 | 
						|
     *  Sets the current chunk to the next available chunk. If no next chunk is present, this function returns
 | 
						|
     *  \c false, otherwise it returns \c true.
 | 
						|
     */
 | 
						|
    bool GotoNextChunk();
 | 
						|
 | 
						|
    /** Returns the SSRC identifier of the current chunk. */
 | 
						|
    uint32_t GetChunkSSRC() const;
 | 
						|
 | 
						|
    /** Starts the iteration over the SDES items in the current chunk.
 | 
						|
     *  Starts the iteration over the SDES items in the current chunk. If no SDES items are
 | 
						|
     *  present, the function returns \c false. Otherwise, the function sets the current item
 | 
						|
     *  to be the first one and returns \c true.
 | 
						|
     */
 | 
						|
    bool GotoFirstItem();
 | 
						|
 | 
						|
    /** Advances the iteration to the next item in the current chunk.
 | 
						|
     *  If there's another item in the chunk, the current item is set to be the next one and the function
 | 
						|
     *  returns \c true. Otherwise, the function returns \c false.
 | 
						|
     */
 | 
						|
    bool GotoNextItem();
 | 
						|
 | 
						|
    /** Returns the SDES item type of the current item in the current chunk. */
 | 
						|
    ItemType GetItemType() const;
 | 
						|
 | 
						|
    /** Returns the item length of the current item in the current chunk. */
 | 
						|
    std::size_t GetItemLength() const;
 | 
						|
 | 
						|
    /** Returns the item data of the current item in the current chunk. */
 | 
						|
    uint8_t *GetItemData();
 | 
						|
 | 
						|
#ifdef RTP_SUPPORT_SDESPRIV
 | 
						|
    /** If the current item is an SDES PRIV item, this function returns the length of the
 | 
						|
     *  prefix string of the private item.
 | 
						|
     */
 | 
						|
    std::size_t GetPRIVPrefixLength() const;
 | 
						|
 | 
						|
    /** If the current item is an SDES PRIV item, this function returns actual data of the
 | 
						|
     *  prefix string.
 | 
						|
     */
 | 
						|
    uint8_t *GetPRIVPrefixData();
 | 
						|
 | 
						|
    /** If the current item is an SDES PRIV item, this function returns the length of the
 | 
						|
     *  value string of the private item.
 | 
						|
     */
 | 
						|
    std::size_t GetPRIVValueLength() const;
 | 
						|
 | 
						|
    /** If the current item is an SDES PRIV item, this function returns actual value data of the
 | 
						|
     *  private item.
 | 
						|
     */
 | 
						|
    uint8_t *GetPRIVValueData();
 | 
						|
#endif // RTP_SUPPORT_SDESPRIV
 | 
						|
 | 
						|
private:
 | 
						|
    RTPEndian m_endian;
 | 
						|
    uint8_t *currentchunk;
 | 
						|
    int curchunknum;
 | 
						|
    std::size_t itemoffset;
 | 
						|
};
 | 
						|
 | 
						|
inline int RTCPSDESPacket::GetChunkCount() const
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return 0;
 | 
						|
    RTCPCommonHeader *hdr = (RTCPCommonHeader *) data;
 | 
						|
    return ((int) hdr->count);
 | 
						|
}
 | 
						|
 | 
						|
inline bool RTCPSDESPacket::GotoFirstChunk()
 | 
						|
{
 | 
						|
    if (GetChunkCount() == 0)
 | 
						|
    {
 | 
						|
        currentchunk = 0;
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
    currentchunk = data + sizeof(RTCPCommonHeader);
 | 
						|
    curchunknum = 1;
 | 
						|
    itemoffset = sizeof(uint32_t);
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
inline bool RTCPSDESPacket::GotoNextChunk()
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return false;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return false;
 | 
						|
    if (curchunknum == GetChunkCount())
 | 
						|
        return false;
 | 
						|
 | 
						|
    std::size_t offset = sizeof(uint32_t);
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + sizeof(uint32_t));
 | 
						|
 | 
						|
    while (sdeshdr->sdesid != 0)
 | 
						|
    {
 | 
						|
        offset += sizeof(RTCPSDESHeader);
 | 
						|
        offset += (std::size_t)(sdeshdr->length);
 | 
						|
        sdeshdr = (RTCPSDESHeader *) (currentchunk + offset);
 | 
						|
    }
 | 
						|
    offset++; // for the zero byte
 | 
						|
    if ((offset & 0x03) != 0)
 | 
						|
        offset += (4 - (offset & 0x03));
 | 
						|
    currentchunk += offset;
 | 
						|
    curchunknum++;
 | 
						|
    itemoffset = sizeof(uint32_t);
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
inline uint32_t RTCPSDESPacket::GetChunkSSRC() const
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return 0;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return 0;
 | 
						|
    uint32_t *ssrc = (uint32_t *) currentchunk;
 | 
						|
    return m_endian.qToHost(*ssrc);
 | 
						|
}
 | 
						|
 | 
						|
inline bool RTCPSDESPacket::GotoFirstItem()
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return false;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return false;
 | 
						|
    itemoffset = sizeof(uint32_t);
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + itemoffset);
 | 
						|
    if (sdeshdr->sdesid == 0)
 | 
						|
        return false;
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
inline bool RTCPSDESPacket::GotoNextItem()
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return false;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return false;
 | 
						|
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + itemoffset);
 | 
						|
    if (sdeshdr->sdesid == 0)
 | 
						|
        return false;
 | 
						|
 | 
						|
    std::size_t offset = itemoffset;
 | 
						|
    offset += sizeof(RTCPSDESHeader);
 | 
						|
    offset += (std::size_t)(sdeshdr->length);
 | 
						|
    sdeshdr = (RTCPSDESHeader *) (currentchunk + offset);
 | 
						|
    if (sdeshdr->sdesid == 0)
 | 
						|
        return false;
 | 
						|
    itemoffset = offset;
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
inline RTCPSDESPacket::ItemType RTCPSDESPacket::GetItemType() const
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return None;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return None;
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + itemoffset);
 | 
						|
    switch (sdeshdr->sdesid)
 | 
						|
    {
 | 
						|
    case 0:
 | 
						|
        return None;
 | 
						|
    case RTCP_SDES_ID_CNAME:
 | 
						|
        return CNAME;
 | 
						|
    case RTCP_SDES_ID_NAME:
 | 
						|
        return NAME;
 | 
						|
    case RTCP_SDES_ID_EMAIL:
 | 
						|
        return EMAIL;
 | 
						|
    case RTCP_SDES_ID_PHONE:
 | 
						|
        return PHONE;
 | 
						|
    case RTCP_SDES_ID_LOCATION:
 | 
						|
        return LOC;
 | 
						|
    case RTCP_SDES_ID_TOOL:
 | 
						|
        return TOOL;
 | 
						|
    case RTCP_SDES_ID_NOTE:
 | 
						|
        return NOTE;
 | 
						|
    case RTCP_SDES_ID_PRIVATE:
 | 
						|
        return PRIV;
 | 
						|
    default:
 | 
						|
        return Unknown;
 | 
						|
    }
 | 
						|
    return Unknown;
 | 
						|
}
 | 
						|
 | 
						|
inline std::size_t RTCPSDESPacket::GetItemLength() const
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return None;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return None;
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + itemoffset);
 | 
						|
    if (sdeshdr->sdesid == 0)
 | 
						|
        return 0;
 | 
						|
    return (std::size_t)(sdeshdr->length);
 | 
						|
}
 | 
						|
 | 
						|
inline uint8_t *RTCPSDESPacket::GetItemData()
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return 0;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return 0;
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + itemoffset);
 | 
						|
    if (sdeshdr->sdesid == 0)
 | 
						|
        return 0;
 | 
						|
    return (currentchunk + itemoffset + sizeof(RTCPSDESHeader));
 | 
						|
}
 | 
						|
 | 
						|
#ifdef RTP_SUPPORT_SDESPRIV
 | 
						|
inline std::size_t RTCPSDESPacket::GetPRIVPrefixLength() const
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return 0;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return 0;
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + itemoffset);
 | 
						|
    if (sdeshdr->sdesid != RTCP_SDES_ID_PRIVATE)
 | 
						|
        return 0;
 | 
						|
    if (sdeshdr->length == 0)
 | 
						|
        return 0;
 | 
						|
    uint8_t *preflen = currentchunk + itemoffset + sizeof(RTCPSDESHeader);
 | 
						|
    std::size_t prefixlength = (std::size_t)(*preflen);
 | 
						|
    if (prefixlength > (std::size_t)((sdeshdr->length) - 1))
 | 
						|
        return 0;
 | 
						|
    return prefixlength;
 | 
						|
}
 | 
						|
 | 
						|
inline uint8_t *RTCPSDESPacket::GetPRIVPrefixData()
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return 0;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return 0;
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + itemoffset);
 | 
						|
    if (sdeshdr->sdesid != RTCP_SDES_ID_PRIVATE)
 | 
						|
        return 0;
 | 
						|
    if (sdeshdr->length == 0)
 | 
						|
        return 0;
 | 
						|
    uint8_t *preflen = currentchunk + itemoffset + sizeof(RTCPSDESHeader);
 | 
						|
    std::size_t prefixlength = (std::size_t)(*preflen);
 | 
						|
    if (prefixlength > (std::size_t)((sdeshdr->length) - 1))
 | 
						|
        return 0;
 | 
						|
    if (prefixlength == 0)
 | 
						|
        return 0;
 | 
						|
    return (currentchunk + itemoffset + sizeof(RTCPSDESHeader) + 1);
 | 
						|
}
 | 
						|
 | 
						|
inline std::size_t RTCPSDESPacket::GetPRIVValueLength() const
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return 0;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return 0;
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + itemoffset);
 | 
						|
    if (sdeshdr->sdesid != RTCP_SDES_ID_PRIVATE)
 | 
						|
        return 0;
 | 
						|
    if (sdeshdr->length == 0)
 | 
						|
        return 0;
 | 
						|
    uint8_t *preflen = currentchunk + itemoffset + sizeof(RTCPSDESHeader);
 | 
						|
    std::size_t prefixlength = (std::size_t)(*preflen);
 | 
						|
    if (prefixlength > (std::size_t)((sdeshdr->length) - 1))
 | 
						|
        return 0;
 | 
						|
    return ((std::size_t)(sdeshdr->length)) - prefixlength - 1;
 | 
						|
}
 | 
						|
 | 
						|
inline uint8_t *RTCPSDESPacket::GetPRIVValueData()
 | 
						|
{
 | 
						|
    if (!knownformat)
 | 
						|
        return 0;
 | 
						|
    if (currentchunk == 0)
 | 
						|
        return 0;
 | 
						|
    RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (currentchunk + itemoffset);
 | 
						|
    if (sdeshdr->sdesid != RTCP_SDES_ID_PRIVATE)
 | 
						|
        return 0;
 | 
						|
    if (sdeshdr->length == 0)
 | 
						|
        return 0;
 | 
						|
    uint8_t *preflen = currentchunk + itemoffset + sizeof(RTCPSDESHeader);
 | 
						|
    std::size_t prefixlength = (std::size_t)(*preflen);
 | 
						|
    if (prefixlength > (std::size_t)((sdeshdr->length) - 1))
 | 
						|
        return 0;
 | 
						|
    std::size_t valuelen = ((std::size_t)(sdeshdr->length)) - prefixlength - 1;
 | 
						|
    if (valuelen == 0)
 | 
						|
        return 0;
 | 
						|
    return (currentchunk + itemoffset + sizeof(RTCPSDESHeader) + 1 + prefixlength);
 | 
						|
}
 | 
						|
 | 
						|
#endif // RTP_SUPPORT_SDESPRIV
 | 
						|
 | 
						|
} // end namespace
 | 
						|
 | 
						|
#endif // RTCPSDESPACKET_H
 | 
						|
 |