blob: e2cdcbdc969568da678c0ba91f979c276a1d55d8 [file] [log] [blame]
/**
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <RtcpChunk.h>
#include <RtpTrace.h>
RtcpChunk::RtcpChunk() :
m_uiSsrc(RTP_ZERO),
m_stSdesItemList(std::list<tRTCP_SDES_ITEM*>())
{
}
RtcpChunk::~RtcpChunk()
{
// delete all tRTCP_SDES_ITEM objects from SdesItemList
for (const auto& pstSdesItem : m_stSdesItemList)
{
if (pstSdesItem->pValue != RTP_NULL)
{
delete[] pstSdesItem->pValue;
}
delete pstSdesItem;
}
m_stSdesItemList.clear();
}
RtpDt_Void RtcpChunk::setSsrc(IN RtpDt_UInt32 uiSsrc)
{
m_uiSsrc = uiSsrc;
}
RtpDt_UInt32 RtcpChunk::getSsrc()
{
return m_uiSsrc;
}
std::list<tRTCP_SDES_ITEM*>& RtcpChunk::getSdesItemList()
{
return m_stSdesItemList;
}
eRTP_STATUS_CODE RtcpChunk::decodeRtcpChunk(IN RtpDt_UChar* pucChunkBuf,
IN RtpDt_UInt16& usChunkLen, IN RtcpConfigInfo* pobjRtcpCfgInfo)
{
// SDES items
RtpDt_UInt32 uiSdesItemCnt = pobjRtcpCfgInfo->getSdesItemCount();
eRtp_Bool bCName = eRTP_FALSE;
while (uiSdesItemCnt > RTP_ZERO)
{
tRTCP_SDES_ITEM* pstSdesItem = new tRTCP_SDES_ITEM();
if (pstSdesItem == RTP_NULL)
{
RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
return RTP_MEMORY_FAIL;
}
memset(pstSdesItem, RTP_ZERO, sizeof(tRTCP_SDES_ITEM));
// type
pstSdesItem->ucType = *(reinterpret_cast<RtpDt_UChar*>(pucChunkBuf));
pucChunkBuf = pucChunkBuf + RTP_ONE;
usChunkLen = usChunkLen + RTP_ONE;
if (pstSdesItem->ucType == RTP_ONE)
{
bCName = eRTP_TRUE;
}
// length
pstSdesItem->ucLength = *(reinterpret_cast<RtpDt_UChar*>(pucChunkBuf));
pucChunkBuf = pucChunkBuf + RTP_ONE;
usChunkLen = usChunkLen + RTP_ONE;
RTP_TRACE_MESSAGE("decodeRtcpChunk , [Sdes item type =%d], [Sdes item length = %d]",
pstSdesItem->ucType, pstSdesItem->ucLength);
// value
RtpDt_UChar* pcSdesBuf = new RtpDt_UChar[pstSdesItem->ucLength];
if (pcSdesBuf == RTP_NULL)
{
RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
delete pstSdesItem;
return RTP_MEMORY_FAIL;
}
memcpy(pcSdesBuf, pucChunkBuf, pstSdesItem->ucLength);
pucChunkBuf = pucChunkBuf + pstSdesItem->ucLength;
usChunkLen = usChunkLen + pstSdesItem->ucLength;
pstSdesItem->pValue = pcSdesBuf;
m_stSdesItemList.push_back(pstSdesItem);
// decrement uiSdesItemCnt by 1
uiSdesItemCnt = uiSdesItemCnt - RTP_ONE;
} // while
if (bCName == eRTP_FALSE)
{
return RTP_DECODE_ERROR;
}
return RTP_SUCCESS;
} // decodeRtcpChunk
eRTP_STATUS_CODE RtcpChunk::formRtcpChunk(OUT RtpBuffer* pobjRtcpPktBuf)
{
RtpDt_UInt32 uiCurPos = pobjRtcpPktBuf->getLength();
RtpDt_UChar* pucBuffer = pobjRtcpPktBuf->getBuffer();
pucBuffer = pucBuffer + uiCurPos;
// m_uiSsrc
*(reinterpret_cast<RtpDt_UInt32*>(pucBuffer)) = RtpOsUtil::Ntohl(m_uiSsrc);
pucBuffer = pucBuffer + RTP_WORD_SIZE;
uiCurPos = uiCurPos + RTP_WORD_SIZE;
eRtp_Bool bCName = eRTP_FALSE;
for (auto& pstSdesItem : m_stSdesItemList)
{
// ucType
*(reinterpret_cast<RtpDt_UChar*>(pucBuffer)) = pstSdesItem->ucType;
pucBuffer = pucBuffer + RTP_ONE;
uiCurPos = uiCurPos + RTP_ONE;
if (pstSdesItem->ucType == RTP_ONE)
{
bCName = eRTP_TRUE;
}
// ucLength
*(reinterpret_cast<RtpDt_UChar*>(pucBuffer)) = pstSdesItem->ucLength;
pucBuffer = pucBuffer + RTP_ONE;
uiCurPos = uiCurPos + RTP_ONE;
// pValue
memcpy(pucBuffer, pstSdesItem->pValue, pstSdesItem->ucLength);
pucBuffer = pucBuffer + pstSdesItem->ucLength;
uiCurPos = uiCurPos + pstSdesItem->ucLength;
// to add type(0)
uiCurPos = uiCurPos + RTP_ONE;
pucBuffer[0] = (RtpDt_UChar)RTP_ZERO;
pucBuffer = pucBuffer + RTP_ONE;
// to align the memory
RtpDt_UInt32 uiPadLen = uiCurPos % RTP_WORD_SIZE;
if (uiPadLen > RTP_ZERO)
{
uiPadLen = RTP_WORD_SIZE - uiPadLen;
uiCurPos = uiCurPos + uiPadLen;
memset(pucBuffer, RTP_ZERO, uiPadLen);
pucBuffer = pucBuffer + uiPadLen;
}
} // for
pobjRtcpPktBuf->setLength(uiCurPos);
if (bCName == eRTP_FALSE)
{
return RTP_ENCODE_ERROR;
}
return RTP_SUCCESS;
} // formRtcpChunk