#if defined(HAVE_CONFIG_H)
#include "common/config.hxx"
#endif
#include "common/Contents.hxx"
#include "common/OctetContents.hxx"
#include "common/HeaderFieldValueList.hxx"
#include "MsrpRoar.h"
#include "common/UnknownHeaderType.hxx"
#include "common/os/Coders.hxx"
#include "common/os/CountStream.hxx"
#include "common/os/Logger.hxx"
#include "common/os/MD5Stream.hxx"
#include "common/os/compat.hxx"
#include "common/os/vmd5.hxx"
#include "common/os/Coders.hxx"
#include "common/os/Random.hxx"
#include "common/os/ParseBuffer.hxx"
#include "common/MsgHeaderScanner.hxx"
#include "common/os/WinLeakCheck.hxx"
using namespace msrp;
using namespace std;
#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
MsrpRoar::MsrpRoar(const Transport* fromWire)
: mIsExternal(fromWire != 0),
mTransport(fromWire),
mStartLine(0),
mContentsHfv(0),
mContents(0),
mRequest(false),
mResponse(false),
mCreatedTime(Timer::getTimeMicroSec()),
mTlsDomain(Data::Empty)
{
for (int i = 0; i < Headers::MAX_HEADERS; i++)
{
mHeaders[i] = 0;
}
}
MsrpRoar::MsrpRoar(const MsrpRoar& from)
: mStartLine(0),
mContentsHfv(0),
mContents(0),
mCreatedTime(Timer::getTimeMicroSec())
{
for (int i = 0; i < Headers::MAX_HEADERS; i++)
{
mHeaders[i] = 0;
}
*this = from;
}
Message*
MsrpRoar::clone() const
{
return new MsrpRoar(*this);
}
MsrpRoar&
MsrpRoar::operator=(const MsrpRoar& rhs)
{
if (this != &rhs)
{
this->cleanUp();
mIsExternal = rhs.mIsExternal;
mTransport = rhs.mTransport;
//mSource = rhs.mSource;
//mDestination = rhs.mDestination;
mStartLine = 0;
mContentsHfv = 0;
mContents = 0;
mRequest = rhs.mRequest;
mResponse = rhs.mResponse;
mTlsDomain = rhs.mTlsDomain;
for (int i = 0; i < Headers::MAX_HEADERS; i++)
{
if (rhs.mHeaders[i] != 0)
{
mHeaders[i] = new HeaderFieldValueList(*rhs.mHeaders[i]);
}
else
{
mHeaders[i] = 0;
}
}
for (UnknownHeaders::const_iterator i = rhs.mUnknownHeaders.begin();
i != rhs.mUnknownHeaders.end(); i++)
{
mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(
i->first,
new HeaderFieldValueList(*i->second)));
}
if (rhs.mStartLine != 0)
{
mStartLine = new HeaderFieldValueList(*rhs.mStartLine);
}
if (rhs.mContents != 0)
{
mContents = rhs.mContents->clone();
}
else if (rhs.mContentsHfv != 0)
{
mContentsHfv = new HeaderFieldValue(*rhs.mContentsHfv);
}
else
{
// no body to copy
}
}
return *this;
}
MsrpRoar::~MsrpRoar()
{
cleanUp();
}
void
MsrpRoar::cleanUp()
{
for (int i = 0; i < Headers::MAX_HEADERS; i++)
{
delete mHeaders[i];
mHeaders[i] = 0;
}
for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
i != mUnknownHeaders.end(); i++)
{
delete i->second;
}
mUnknownHeaders.clear();
for (vector<char*>::iterator i = mBufferList.begin();
i != mBufferList.end(); i++)
{
delete [] *i;
}
mBufferList.clear();
delete mStartLine;
mStartLine = 0;
delete mContents;
mContents = 0;
delete mContentsHfv;
mContentsHfv = 0;
}
MsrpRoar*
MsrpRoar::make(const Data& data, bool isExternal)
{
Transport* external = (Transport*)(0xFFFF);
MsrpRoar* msg = new MsrpRoar(isExternal ? external : 0);
size_t len = data.size();
char *buffer = new char[len + 5];
msg->addBuffer(buffer);
memcpy(buffer,data.data(), len);
MsgHeaderScanner msgHeaderScanner;
msgHeaderScanner.prepareForMessage(msg);
char *unprocessedCharPtr;
if (msgHeaderScanner.scanChunk(buffer, len, &unprocessedCharPtr) != MsgHeaderScanner::scrEnd)
{
DebugLog(<<"Scanner rejecting buffer as unparsable / fragmented.");
DebugLog(<< data);
delete msg;
msg = 0;
return 0;
}
// no pp error
unsigned int used = unprocessedCharPtr - buffer;
if (used < len)
{
// body is present .. add it up.
// NB. The Sip Roar uses an overlay (again)
// for the body. It ALSO expects that the body
// will be contiguous (of course).
// it doesn't need a new buffer in UDP b/c there
// will only be one datagram per buffer. (1:1 strict)
msg->setBody(buffer+used,len-used);
//DebugLog(<<"added " << len-used << " byte body");
}
return msg;
}
const Data&
MsrpRoar::getTransactionId() const
{
if (0 == mStartLine)
{
InfoLog( << "Missing start line " );
throw Exception("Missing start line", __FILE__, __LINE__);
}
if (mRequest)
{
assert(!mResponse);
return (dynamic_cast<ParserContainer<MsrpRequestLine>*>(mStartLine->getParserContainer())->front()).transactionId();
}
else
{
assert(!mRequest);
return (dynamic_cast<ParserContainer<MsrpStatusLine>*>(mStartLine->getParserContainer())->front()).transactionId();
}
}
bool
MsrpRoar::isRequest() const
{
return mRequest;
}
bool
MsrpRoar::isResponse() const
{
return mResponse;
}
Data
MsrpRoar::brief() const
{
Data result(128, true);
#if 0
static const Data request("SipReq: ");
static const Data response("SipResp: ");
static const Data tid(" tid=");
static const Data contact(" contact=");
static const Data cseq(" cseq=");
static const Data slash(" / ");
static const Data wire(" from(wire)");
static const Data tu(" from(tu)");
// !dlb! should be checked earlier
#if 0
if (!exists(h_CSeq))
{
result = "MALFORMED; missing CSeq";
return result;
}
if (!exists(h_CallId))
{
result = "MALFORMED; missing Call-Id";
return result;
}
#endif
if (isRequest())
{
result += request;
MethodTypes meth = header(h_RequestLine).getMethod();
if (meth != UNKNOWN)
{
result += getMethodName(meth);
}
else
{
result += header(h_RequestLine).unknownMethodName();
}
result += Symbols::SPACE;
result += header(h_RequestLine).uri().getAor();
}
else if (isResponse())
{
result += response;
result += Data(header(h_StatusLine).responseCode());
}
if (exists(h_Vias) && !this->header(h_Vias).empty())
{
result += tid;
result += getTransactionId();
}
else
{
result += " NO-VIAS ";
}
result += cseq;
if (header(h_CSeq).method() != UNKNOWN)
{
result += getMethodName(header(h_CSeq).method());
}
else
{
result += header(h_CSeq).unknownMethodName();
}
if (exists(h_Contacts) && !header(h_Contacts).empty())
{
result += contact;
result += header(h_Contacts).front().uri().getAor();
}
result += slash;
result += Data(header(h_CSeq).sequence());
result += mIsExternal ? wire : tu;
#endif
return result;
}
bool
MsrpRoar::isClientTransaction() const
{
assert(mRequest || mResponse);
return ((mIsExternal && mResponse) || (!mIsExternal && mRequest));
}
// dynamic_cast &str to DataStream* to avoid CountStream?
std::ostream&
MsrpRoar::encode(std::ostream& str) const
{
if (mStartLine != 0)
{
mStartLine->encode(Data::Empty, str);
}
for (int i = 0; i < Headers::MAX_HEADERS; i++)
{
if (i != Headers::ContentLength) // !dlb! hack...
{
if (mHeaders[i] != 0)
{
mHeaders[i]->encode(i, str);
}
}
else
{
if (mContents != 0)
{
size_t size;
{
CountStream cs(size);
mContents->encode(cs);
}
str << "Content-Length: " << size << "\r\n";
}
else if (mContentsHfv != 0)
{
str << "Content-Length:
MSRP.zip_SIP Client MSRP_msrp_msrp sip_sip_sip msrp
版权申诉
5星 · 超过95%的资源 170 浏览量
2022-09-19
13:07:27
上传
评论
收藏 56KB ZIP 举报
Kinonoyomeo
- 粉丝: 75
- 资源: 1万+
最新资源
- 基于flask和echarts融合交易策略的bitfinex可视化微服务.zip
- 包含了wvp-assist.tar wvp-talk.tar zlmediakit.tar .
- 3r4efgh53wgrf43tw
- 2024新版Java基础从入门到精通全套视频+资料下载
- Spring AI大模型视频教程+ChatGPT视频教程+OpenAI大模型视频教程(资料+视频教程)
- ABB工业机器人教程PDF版本
- 123321123323211
- yolov8实战第八天-pyqt5-yolov8实现车牌识别系统(论文(约7000字)+数据集+完整部署代码+代码使用说明)
- 三相桥式全桥整流电路MATALB Simulink仿真文件
- ABB机器人操作培训文档
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈