#define MS_CLASS "RTC::SCTP::ReconfigurationResponseParameter"
#include "RTC/SCTP/packet/parameters/ReconfigurationResponseParameter.hpp"
#include "Logger.hpp"
#include "MediaSoupErrors.hpp"
namespace RTC
{
namespace SCTP
{
const ankerl::unordered_dense::map<ReconfigurationResponseParameter::Result, std::string> ReconfigurationResponseParameter::Result2String =
{
{ ReconfigurationResponseParameter::Result::SUCCESS_NOTHING_TO_DO, "SUCCESS_NOTHING_TO_DO" },
{ ReconfigurationResponseParameter::Result::SUCCESS_PERFORMED, "SUCCESS_PERFORMED" },
{ ReconfigurationResponseParameter::Result::DENIED, "DENIED" },
{ ReconfigurationResponseParameter::Result::ERROR_WRONG_SSN, "ERROR_WRONG_SSN" },
{ ReconfigurationResponseParameter::Result::ERROR_REQUEST_ALREADY_IN_PROGRESS, "ERROR_REQUEST_ALREADY_IN_PROGRESS" },
{ ReconfigurationResponseParameter::Result::ERROR_BAD_SEQUENCE_NUMBER, "ERROR_BAD_SEQUENCE_NUMBER" },
{ ReconfigurationResponseParameter::Result::IN_PROGRESS, "IN_PROGRESS" },
};
ReconfigurationResponseParameter* ReconfigurationResponseParameter::Parse(
const uint8_t* buffer, size_t bufferLength)
{
MS_TRACE();
Parameter::ParameterType parameterType;
uint16_t parameterLength;
uint8_t padding;
if (!Parameter::IsParameter(buffer, bufferLength, parameterType, parameterLength, padding))
{
return nullptr;
}
if (parameterType != Parameter::ParameterType::RECONFIGURATION_RESPONSE)
{
MS_WARN_DEV("invalid parameter type");
return nullptr;
}
return ReconfigurationResponseParameter::ParseStrict(
buffer, bufferLength, parameterLength, padding);
}
ReconfigurationResponseParameter* ReconfigurationResponseParameter::Factory(
uint8_t* buffer, size_t bufferLength)
{
MS_TRACE();
if (bufferLength < ReconfigurationResponseParameter::ReconfigurationResponseParameterHeaderLength)
{
MS_THROW_TYPE_ERROR("buffer too small");
}
auto* parameter = new ReconfigurationResponseParameter(buffer, bufferLength);
parameter->InitializeHeader(
Parameter::ParameterType::RECONFIGURATION_RESPONSE,
ReconfigurationResponseParameter::ReconfigurationResponseParameterHeaderLength);
parameter->SetReconfigurationResponseSequenceNumber(0);
parameter->SetResult(static_cast<Result>(0));
return parameter;
}
const std::string& ReconfigurationResponseParameter::ResultToString(
ReconfigurationResponseParameter::Result result)
{
MS_TRACE();
static const std::string Unknown("UNKNOWN");
auto it = ReconfigurationResponseParameter::Result2String.find(result);
if (it == ReconfigurationResponseParameter::Result2String.end())
{
return Unknown;
}
return it->second;
}
ReconfigurationResponseParameter* ReconfigurationResponseParameter::ParseStrict(
const uint8_t* buffer, size_t bufferLength, uint16_t parameterLength, uint8_t padding)
{
MS_TRACE();
if (
parameterLength !=
ReconfigurationResponseParameter::ReconfigurationResponseParameterHeaderLength &&
parameterLength !=
ReconfigurationResponseParameter::ReconfigurationResponseParameterHeaderLengthWithOptionalFields)
{
MS_WARN_TAG(
sctp,
"ReconfigurationResponseParameter length field must be %zu or %zu",
ReconfigurationResponseParameter::ReconfigurationResponseParameterHeaderLength,
ReconfigurationResponseParameter::ReconfigurationResponseParameterHeaderLengthWithOptionalFields);
return nullptr;
}
auto* parameter =
new ReconfigurationResponseParameter(const_cast<uint8_t*>(buffer), bufferLength);
parameter->SetLength(parameterLength + padding);
return parameter;
}
ReconfigurationResponseParameter::ReconfigurationResponseParameter(uint8_t* buffer, size_t bufferLength)
: Parameter(buffer, bufferLength)
{
MS_TRACE();
SetLength(ReconfigurationResponseParameter::ReconfigurationResponseParameterHeaderLength);
}
ReconfigurationResponseParameter::~ReconfigurationResponseParameter()
{
MS_TRACE();
}
void ReconfigurationResponseParameter::Dump(int indentation) const
{
MS_TRACE();
MS_DUMP_CLEAN(indentation, "<SCTP::ReconfigurationResponseParameter>");
DumpCommon(indentation);
MS_DUMP_CLEAN(
indentation,
" re-configuration response sequence number: %" PRIu32,
GetReconfigurationResponseSequenceNumber());
MS_DUMP_CLEAN(
indentation,
" result: %" PRIu32 " (%s)",
static_cast<uint32_t>(GetResult()),
ReconfigurationResponseParameter::ResultToString(GetResult()).c_str());
MS_DUMP_CLEAN(indentation, " has next tsns: %s", HasNextTsns() ? "yes" : "no");
if (HasNextTsns())
{
MS_DUMP_CLEAN(indentation, " sender next tsn: %" PRIu32, GetSenderNextTsn());
MS_DUMP_CLEAN(indentation, " receiver next tsn: %" PRIu32, GetReceiverNextTsn());
}
MS_DUMP_CLEAN(indentation, "</SCTP::ReconfigurationResponseParameter>");
}
ReconfigurationResponseParameter* ReconfigurationResponseParameter::Clone(
uint8_t* buffer, size_t bufferLength) const
{
MS_TRACE();
auto* clonedParameter = new ReconfigurationResponseParameter(buffer, bufferLength);
CloneInto(clonedParameter);
return clonedParameter;
}
void ReconfigurationResponseParameter::SetReconfigurationResponseSequenceNumber(uint32_t value)
{
MS_TRACE();
Utils::Byte::Set4Bytes(const_cast<uint8_t*>(GetBuffer()), 4, value);
}
void ReconfigurationResponseParameter::SetResult(Result result)
{
MS_TRACE();
Utils::Byte::Set4Bytes(const_cast<uint8_t*>(GetBuffer()), 8, static_cast<uint32_t>(result));
}
void ReconfigurationResponseParameter::SetNextTsns(uint32_t senderNextTsn, uint32_t receiverNextTsn)
{
MS_TRACE();
if (!HasNextTsns())
{
SetVariableLengthValueLength(
ReconfigurationResponseParameter::ReconfigurationResponseParameterHeaderLengthWithOptionalFields -
ReconfigurationResponseParameter::ReconfigurationResponseParameterHeaderLength);
}
Utils::Byte::Set4Bytes(const_cast<uint8_t*>(GetBuffer()), 12, senderNextTsn);
Utils::Byte::Set4Bytes(const_cast<uint8_t*>(GetBuffer()), 16, receiverNextTsn);
}
ReconfigurationResponseParameter* ReconfigurationResponseParameter::SoftClone(
const uint8_t* buffer) const
{
MS_TRACE();
auto* softClonedParameter =
new ReconfigurationResponseParameter(const_cast<uint8_t*>(buffer), GetLength());
SoftCloneInto(softClonedParameter);
return softClonedParameter;
}
} }