📄 deprecateddialog.cxx
字号:
#if defined(HAVE_CONFIG_H)
#include "resip/stack/config.hxx"
#endif
#include <iostream>
#include "resip/stack/DeprecatedDialog.hxx"
#include "resip/stack/SipMessage.hxx"
#include "resip/stack/Uri.hxx"
#include "resip/stack/NameAddr.hxx"
#include "resip/stack/Helper.hxx"
#include "rutil/Logger.hxx"
#include "rutil/Inserter.hxx"
#include "rutil/WinLeakCheck.hxx"
using namespace resip;
#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
DeprecatedDialog::DeprecatedDialog(const NameAddr& localContact)
: mContact(localContact),
mCreated(false),
mEarly(false),
mRouteSet(),
mRemoteTarget(),
mRemoteSequence(0),
mRemoteEmpty(true),
mLocalSequence(0),
mLocalEmpty(true),
mCallId(),
mLocalTag(),
mRemoteTag(),
mRemoteUri(),
mLocalUri()
{
}
SipMessage*
DeprecatedDialog::makeResponse(const SipMessage& request, int code)
{
assert( code >= 100 );
if ( (!mCreated) && (code < 300) && (code > 100) )
{
assert (code > 100);
assert (code < 300);
assert(request.isRequest());
assert(request.header(h_RequestLine).getMethod() == INVITE ||
request.header(h_RequestLine).getMethod() == SUBSCRIBE ||
request.header(h_RequestLine).getMethod() == PUBLISH);
assert (request.header(h_Contacts).size() == 1);
SipMessage* response = Helper::makeResponse(request, code, mContact);
if (request.exists(h_RecordRoutes))
{
mRouteSet = request.header(h_RecordRoutes);
}
if (!request.exists(h_Contacts) && request.header(h_Contacts).size() != 1)
{
InfoLog (<< "Request doesn't have a contact header or more than one contact, so can't create dialog");
DebugLog (<< request);
throw Exception("Invalid or missing contact header in request", __FILE__,__LINE__);
}
mRemoteTarget = request.header(h_Contacts).front();
mRemoteSequence = request.header(h_CSeq).sequence();
mRemoteEmpty = false;
mLocalSequence = 0;
mLocalEmpty = true;
mCallId = request.header(h_CallId);
response->header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize);
assert (response->header(h_To).exists(p_tag));
mLocalTag = response->header(h_To).param(p_tag); // from response
if (request.header(h_From).exists(p_tag)) // 2543 compat
{
mRemoteTag = request.header(h_From).param(p_tag);
}
mRemoteUri = request.header(h_From);
mLocalUri = request.header(h_To);
mDialogId = mCallId;
mDialogId.param(p_toTag) = mLocalTag;
mDialogId.param(p_fromTag) = mRemoteTag;
mEarly = (code < 200);
mCreated = true;
return response;
}
else
{
SipMessage* response = Helper::makeResponse(request, code, mContact);
if (mCreated)
{
response->header(h_To).param(p_tag) = mLocalTag;
}
//DebugLog(<< "Created response within dialog: " << *response);
return response;
}
}
void
DeprecatedDialog::createDialogAsUAC(const SipMessage& msg)
{
if (!mCreated)
{
if(msg.isResponse())
{
const SipMessage& response = msg;
int code = response.header(h_StatusLine).statusCode();
mEarly = (code > 100 && code < 200);
if (code >= 200 && code < 300)
{
if (!response.exists(h_Contacts) || response.header(h_Contacts).size() != 1)
{
InfoLog (<< "Response doesn't have a contact header or more than one contact, so can't create dialog");
DebugLog (<< response);
throw Exception("Invalid or missing contact header in message", __FILE__,__LINE__);
}
}
// reverse order from response
if (response.exists(h_RecordRoutes))
{
mRouteSet = response.header(h_RecordRoutes).reverse();
}
if (response.exists(h_Contacts) && !response.header(h_Contacts).empty())
{
mRemoteTarget = response.header(h_Contacts).front();
}
mRemoteSequence = 0;
mRemoteEmpty = true;
mLocalSequence = response.header(h_CSeq).sequence();
mLocalEmpty = false;
mCallId = response.header(h_CallId);
if ( response.header(h_From).exists(p_tag) ) // 2543 compat
{
mLocalTag = response.header(h_From).param(p_tag);
}
if ( response.header(h_To).exists(p_tag) ) // 2543 compat
{
mRemoteTag = response.header(h_To).param(p_tag);
}
mRemoteUri = response.header(h_To);
mLocalUri = response.header(h_From);
mDialogId = mCallId;
mDialogId.param(p_toTag) = mLocalTag;
mDialogId.param(p_fromTag) = mRemoteTag;
mCreated = true;
}
else if (msg.isRequest() && msg.header(h_CSeq).method() == NOTIFY)
{
const SipMessage& notify = msg;
if (notify.exists(h_RecordRoutes))
{
mRouteSet = notify.header(h_RecordRoutes);
}
if (!notify.exists(h_Contacts) && notify.header(h_Contacts).size() != 1)
{
InfoLog (<< "Notify doesn't have a contact header or more than one contact, so can't create dialog");
DebugLog (<< notify);
throw Exception("Invalid or missing contact header in notify", __FILE__,__LINE__);
}
mRemoteTarget = notify.header(h_Contacts).front();
mRemoteSequence = notify.header(h_CSeq).sequence();
mRemoteEmpty = false;
mLocalSequence = 0;
mLocalEmpty = true;
mCallId = notify.header(h_CallId);
if (notify.header(h_To).exists(p_tag))
{
mLocalTag = notify.header(h_To).param(p_tag);
}
if (notify.header(h_From).exists(p_tag)) // 2543 compat
{
mRemoteTag = notify.header(h_From).param(p_tag);
}
mRemoteUri = notify.header(h_From);
mLocalUri = notify.header(h_To);
mDialogId = mCallId;
mDialogId.param(p_toTag) = mLocalTag;
mDialogId.param(p_fromTag) = mRemoteTag;
mCreated = true;
mEarly = false;
}
}
else if (msg.isResponse())
{
mEarly = (msg.header(h_StatusLine).statusCode() < 200 &&
msg.header(h_StatusLine).statusCode() > 100);
// don't update target for register since contact is not a target
if ( msg.header(h_CSeq).method() != REGISTER )
{
targetRefreshResponse(msg);
}
}
}
void
DeprecatedDialog::targetRefreshResponse(const SipMessage& response)
{
if (response.exists(h_Contacts) && response.header(h_Contacts).size() == 1)
{
mRemoteTarget = response.header(h_Contacts).front();
}
}
int
DeprecatedDialog::targetRefreshRequest(const SipMessage& request)
{
assert (request.header(h_RequestLine).getMethod() != CANCEL);
if (request.header(h_RequestLine).getMethod() != ACK)
{
unsigned long cseq = request.header(h_CSeq).sequence();
if (mRemoteEmpty)
{
mRemoteSequence = cseq;
mRemoteEmpty = false;
}
else if (cseq < mRemoteSequence)
{
InfoLog (<< "Got a cseq out of sequence: " << cseq << " < " << mRemoteSequence);
throw Exception("out of order", __FILE__,__LINE__);
}
else
{
mRemoteSequence = cseq;
}
if (request.exists(h_Contacts) && request.header(h_Contacts).size() == 1)
{
mRemoteTarget = request.header(h_Contacts).front();
}
else
{
InfoLog (<< "Request doesn't have a contact header or more than one contact, so can't create dialog");
DebugLog (<< request);
throw Exception("Invalid or missing contact header in message", __FILE__,__LINE__);
}
}
return 0;
}
void
DeprecatedDialog::updateRequest(SipMessage& request)
{
assert (request.isRequest());
if (mCreated)
{
request.header(h_RequestLine).uri() = mRemoteTarget.uri();
request.header(h_To) = mRemoteUri;
if ( !mRemoteTag.empty() )
{
request.header(h_To).param(p_tag) = mRemoteTag;
}
request.header(h_From) = mLocalUri;
if ( !mLocalTag.empty() )
{
request.header(h_From).param(p_tag) = mLocalTag;
}
request.header(h_CallId) = mCallId;
request.header(h_Routes) = mRouteSet;
request.header(h_Contacts).clear();
request.header(h_Contacts).push_back(mContact);
copyCSeq(request);
incrementCSeq(request);
request.header(h_MaxForwards).value() = 70;
Via via;
via.param(p_branch); // will create the branch
request.header(h_Vias).clear();
request.header(h_Vias).push_back(via);
request.clearForceTarget();
Helper::processStrictRoute(request);
}
else
{
DebugLog (<< "Updating a request when not in a dialog yet");
}
}
void
DeprecatedDialog::makeResponse(const SipMessage& request, SipMessage& response, int code)
{
assert(request.isRequest());
if ( (!mCreated) && (code < 300) && (code > 100) )
{
assert(request.header(h_RequestLine).getMethod() == INVITE ||
request.header(h_RequestLine).getMethod() == SUBSCRIBE);
assert (request.header(h_Contacts).size() == 1);
Helper::makeResponse(response, request, code, mContact);
response.header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize);
if (request.exists(h_RecordRoutes))
{
mRouteSet = request.header(h_RecordRoutes);
}
if (!request.exists(h_Contacts) && request.header(h_Contacts).size() != 1)
{
InfoLog (<< "Request doesn't have a contact header or more than one contact, so can't create dialog");
DebugLog (<< request);
throw Exception("Invalid or missing contact header in request", __FILE__,__LINE__);
}
mRemoteTarget = request.header(h_Contacts).front();
mRemoteSequence = request.header(h_CSeq).sequence();
mRemoteEmpty = false;
mLocalSequence = 0;
mLocalEmpty = true;
mCallId = request.header(h_CallId);
assert (response.header(h_To).exists(p_tag));
mLocalTag = response.header(h_To).param(p_tag); // from response
if (request.header(h_From).exists(p_tag)) // 2543 compat
{
mRemoteTag = request.header(h_From).param(p_tag);
}
mRemoteUri = request.header(h_From);
mLocalUri = request.header(h_To);
mDialogId = mCallId;
mDialogId.param(p_toTag) = mLocalTag;
mDialogId.param(p_fromTag) = mRemoteTag;
mEarly = (code > 100 && code < 200);
mCreated = true;
}
else
{
Helper::makeResponse(response, request, code, mContact);
if (mCreated)
{
response.header(h_To).param(p_tag) = mLocalTag;
mEarly = false;
}
}
}
SipMessage*
DeprecatedDialog::makeInitialRegister(const NameAddr& registrar, const NameAddr& aor)
{
SipMessage* msg = Helper::makeRegister( registrar, aor, mContact );
assert( msg );
mRequestUri = msg->header(h_RequestLine).uri();
mLocalEmpty = false;
mLocalSequence = msg->header(h_CSeq).sequence();
mCallId = msg->header(h_CallId);
assert(msg->header(h_From).exists(p_tag));
mLocalTag = msg->header(h_From).param(p_tag);
mRemoteUri = msg->header(h_To);
mLocalUri = msg->header(h_From);
mCreated = true;
mRemoteTarget = mRemoteUri;
return msg;
}
SipMessage*
DeprecatedDialog::makeInitialSubscribe(const NameAddr& target, const NameAddr& from)
{
SipMessage* msg = Helper::makeSubscribe( target, from, mContact );
assert( msg );
mRequestUri = msg->header(h_RequestLine).uri();
mLocalEmpty = false;
mLocalSequence = msg->header(h_CSeq).sequence();
mCallId = msg->header(h_CallId);
assert(msg->header(h_From).exists(p_tag));
mLocalTag = msg->header(h_From).param(p_tag);
mRemoteUri = msg->header(h_To);
mLocalUri = msg->header(h_From);
return msg;
}
SipMessage*
DeprecatedDialog::makeInitialPublish(const NameAddr& target, const NameAddr& from)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -