mirror of
https://github.com/resiprocate/resiprocate.git
synced 2026-01-12 00:05:02 +08:00
- update resip stacks internal uses of Pidf to GenericPidfContents - remove Pidf.hxx/cxx and tests from build - leave files in place (for now) to allow use if still needed - fixes ContentsFactory ambiguity over which Contents class to use when parsing
4729 lines
129 KiB
C++
4729 lines
129 KiB
C++
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "cppunit/TestCase.h"
|
|
|
|
#include "resip/stack/DeprecatedDialog.hxx"
|
|
#include "resip/stack/Helper.hxx"
|
|
#include "resip/stack/PlainContents.hxx"
|
|
#include "resip/stack/SdpContents.hxx"
|
|
#include "resip/stack/CpimContents.hxx" // vk
|
|
#include "resip/stack/GenericPidfContents.hxx" // vk
|
|
#include "resip/stack/ExtensionParameter.hxx"
|
|
#include "resip/stack/SipFrag.hxx"
|
|
#include "resip/stack/SipMessage.hxx"
|
|
#include "resip/stack/SipStack.hxx"
|
|
#include "resip/stack/TcpTransport.hxx"
|
|
|
|
#ifdef USE_SSL
|
|
#include "resip/stack/ssl/TlsTransport.hxx"
|
|
#endif // USE_SSL
|
|
|
|
#include "resip/stack/UdpTransport.hxx"
|
|
#include "resip/stack/UnknownHeaderType.hxx"
|
|
#include "rutil/Inserter.hxx"
|
|
#include "rutil/Inserter.hxx"
|
|
#include "rutil/Logger.hxx"
|
|
#include "rutil/Random.hxx"
|
|
#include "rutil/DnsUtil.hxx"
|
|
|
|
#include "tfm/DialogSet.hxx"
|
|
#include "tfm/PortAllocator.hxx"
|
|
#include "tfm/Resolver.hxx"
|
|
#include "tfm/Sequence.hxx"
|
|
#include "tfm/SequenceSet.hxx"
|
|
#include "tfm/SipEvent.hxx"
|
|
#include "tfm/SipRawMessage.hxx"
|
|
#include "tfm/TestSipEndPoint.hxx"
|
|
#include "tfm/TestProxy.hxx"
|
|
#include "tfm/TestUser.hxx"
|
|
|
|
#include <utility>
|
|
|
|
using namespace resip;
|
|
using namespace std;
|
|
|
|
#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST
|
|
|
|
std::shared_ptr<resip::SipMessage> TestSipEndPoint::nil;
|
|
resip::Uri TestSipEndPoint::NoOutboundProxy;
|
|
|
|
TestSipEndPoint::IdentityMessageConditioner TestSipEndPoint::identity;
|
|
TestSipEndPoint::IdentityRawConditioner TestSipEndPoint::raw_identity;
|
|
|
|
TestSipEndPoint::TestSipEndPoint(const Uri& addressOfRecord,
|
|
const Uri& contactUrl,
|
|
const Uri& outboundProxy,
|
|
bool hasStack,
|
|
const Data& interfaceObj,
|
|
Security* security)
|
|
: mAor(addressOfRecord),
|
|
mContact(contactUrl),
|
|
mOutboundProxy(outboundProxy),
|
|
mTransport(0),
|
|
mSecurity(security)
|
|
{
|
|
#ifdef RTP_ON
|
|
mRtpSession = 0;
|
|
#endif
|
|
|
|
nwIf=interfaceObj;
|
|
|
|
if(nwIf.empty())
|
|
{
|
|
nwIf=mContact.uri().host();
|
|
}
|
|
|
|
if (hasStack)
|
|
{
|
|
resip::IpVersion version=resip::V4;
|
|
|
|
if(resip::DnsUtil::isIpV6Address(interfaceObj))
|
|
{
|
|
#ifdef USE_IPV6
|
|
version=resip::V6;
|
|
#else
|
|
return;
|
|
#endif
|
|
}
|
|
else if(resip::DnsUtil::isIpV4Address(interfaceObj))
|
|
{
|
|
version=resip::V4;
|
|
}
|
|
|
|
if (!mContact.uri().exists(p_transport) ||
|
|
(isEqualNoCase(mContact.uri().param(p_transport), Tuple::toData(UDP))))
|
|
{
|
|
InfoLog(<< "TestSipEndPoint[" << addressOfRecord << "]transport is UDP " << nwIf);
|
|
mTransport = new UdpTransport(mIncoming, mContact.uri().port(), version, StunDisabled, nwIf,0,resip::Compression::Disabled);
|
|
}
|
|
else if (isEqualNoCase(mContact.uri().param(p_transport), Tuple::toData(TCP)))
|
|
{
|
|
InfoLog(<< "TestSipEndPoint[" << addressOfRecord << "]transport is TCP " << nwIf);
|
|
mTransport = new TcpTransport(mIncoming, mContact.uri().port(), version, nwIf, 0, resip::Compression::Disabled, 0);
|
|
}
|
|
else if (isEqualNoCase(mContact.uri().param(p_transport), Tuple::toData(SCTP)))
|
|
{
|
|
InfoLog(<< "TestSipEndPoint[" << addressOfRecord << "]transport is SCTP INADDR_ANY ("<< nwIf <<" will go in Vias)");
|
|
// .bwc. For SCTP, attach to INADDR_ANY, so we can test multihoming.
|
|
// Also recall that we've added a bool param that switches the behavior
|
|
// of TcpTransport to instead use SCTP.
|
|
mTransport = new TcpTransport(mIncoming, mContact.uri().port(), version, "0.0.0.0", 0, resip::Compression::Disabled, 0);
|
|
}
|
|
#ifdef USE_SSL
|
|
else if (isEqualNoCase(mContact.uri().param(p_transport), Tuple::toData(TLS)))
|
|
{
|
|
InfoLog(<< "TestSipEndPoint[" << addressOfRecord << "]transport is TLS " << nwIf);
|
|
mTransport = new TlsTransport(mIncoming, mContact.uri().port(), version, nwIf,
|
|
*mSecurity, resip::Data::Empty, SecurityTypes::TLSv1, 0, resip::Compression::Disabled, 0);
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
resip_assert(0);
|
|
}
|
|
|
|
resip_assert(mTransport);
|
|
registerWithTransportDriver();
|
|
}
|
|
else
|
|
{
|
|
InfoLog (<< "Creating sip endpoint with no transport: " << addressOfRecord);
|
|
}
|
|
mContactSet.insert(mContact);
|
|
}
|
|
|
|
TestSipEndPoint::TestSipEndPoint(const Uri& contactUrl,
|
|
const Uri& outboundProxy,
|
|
bool hasStack,
|
|
const Data& interfaceObj,
|
|
Security* security)
|
|
: mAor(contactUrl),
|
|
mContact(contactUrl),
|
|
mOutboundProxy(outboundProxy),
|
|
mTransport(0),
|
|
mSecurity(security)
|
|
{
|
|
#ifdef RTP_ON
|
|
mRtpSession = 0;
|
|
#endif
|
|
|
|
DebugLog(<< "TestSipEndPoint::TestSipEndPoint contact: " << mContact);
|
|
if (hasStack)
|
|
{
|
|
resip::IpVersion version = (DnsUtil::isIpV6Address(interfaceObj) ? V6 : V4);
|
|
|
|
if (!contactUrl.exists(p_transport) ||
|
|
(contactUrl.param(p_transport) == Tuple::toData(UDP)))
|
|
{
|
|
//CerrLog(<< "transport is UDP " << interfaceObj);
|
|
mTransport = new UdpTransport(mIncoming, mContact.uri().port(), version, StunDisabled, interfaceObj);
|
|
}
|
|
else if (contactUrl.param(p_transport) == Tuple::toData(TCP))
|
|
{
|
|
//CerrLog(<< "transport is TCP " << interfaceObj);
|
|
mTransport = new TcpTransport(mIncoming, mContact.uri().port(), version, interfaceObj);
|
|
}
|
|
/*
|
|
else if (contactUrl.param(p_transport) == Tuple::toData(Transport::TLS))
|
|
{
|
|
mTransport = new TlsTransport(interfaceObj, mContact.uri().port(), "", mIncoming);
|
|
}
|
|
*/
|
|
|
|
resip_assert(mTransport);
|
|
registerWithTransportDriver();
|
|
}
|
|
mContactSet.insert(mContact);
|
|
}
|
|
|
|
TestSipEndPoint::~TestSipEndPoint()
|
|
{
|
|
DebugLog (<< "Deleting TestSipEndPoint " << getName());
|
|
|
|
unregisterFromTransportDriver();
|
|
delete mTransport;
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::clean()
|
|
{
|
|
DebugLog(<< *this << " Clearing out requests.");
|
|
mInvitesSent.clear();
|
|
mInvitesReceived.clear();
|
|
mUpdatesSent.clear();
|
|
mUpdatesReceived.clear();
|
|
mSubscribesSent.clear();
|
|
mSubscribesReceived.clear();
|
|
mRequests.clear();
|
|
|
|
for (DialogList::iterator it = mDialogs.begin(); it != mDialogs.end(); it++)
|
|
{
|
|
delete (*it);
|
|
}
|
|
mDialogs.clear();
|
|
mLastMessage.reset();
|
|
#ifdef RTP_ON
|
|
delete mRtpSession;
|
|
mRtpSession = 0;
|
|
#endif
|
|
|
|
TestEndPoint::clear();
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::setTransport(Transport* transport)
|
|
{
|
|
resip_assert(transport && !mTransport);
|
|
if (transport && !mTransport)
|
|
{
|
|
mTransport = transport;
|
|
registerWithTransportDriver();
|
|
}
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::send(const std::shared_ptr<SipMessage>& msg, RawConditionerFn func)
|
|
{
|
|
const Tuple* useTuple = 0;
|
|
|
|
Uri uri;
|
|
if (msg->isRequest())
|
|
{
|
|
resip_assert(!msg->header(h_Vias).empty());
|
|
|
|
if( !msg->header(h_Vias).front().exists(p_branch) ||
|
|
msg->header(h_Vias).front().param(p_branch).getTransactionId().empty())
|
|
{
|
|
// .bwc. Hide 2543 tid in topmost via where receiver won't notice
|
|
// it. We will see this over in X when responses come back.
|
|
static ExtensionParameter p_brunch("brunch");
|
|
msg->header(h_Vias).front().param(p_brunch)=msg->getTransactionId();
|
|
}
|
|
|
|
if (msg->header(h_RequestLine).getMethod() != ACK)
|
|
{
|
|
mRequests[msg->getTransactionId()] = msg;
|
|
}
|
|
|
|
//DebugLog (<< "Sending: " << Inserter(mRequests));
|
|
|
|
if (msg->exists(h_Routes) && !msg->header(h_Routes).empty())
|
|
{
|
|
uri = msg->header(h_Routes).front().uri();
|
|
DebugLog(<< "sending based on routes: " << uri);
|
|
}
|
|
else if (mOutboundProxy != TestSipEndPoint::NoOutboundProxy)
|
|
{
|
|
uri = mOutboundProxy;
|
|
}
|
|
else
|
|
{
|
|
uri = msg->header(h_RequestLine).uri();
|
|
}
|
|
}
|
|
else if (msg->isResponse())
|
|
{
|
|
resip_assert (!msg->header(h_Vias).empty());
|
|
Via& via = msg->header(h_Vias).front();
|
|
|
|
// use tuple from request if it exists
|
|
if (msg->header(h_Vias).front().exists(p_branch))
|
|
{
|
|
RequestMap::const_iterator i =
|
|
mRequests.find(msg->header(h_Vias).front().param(p_branch).getTransactionId());
|
|
if (i != mRequests.end())
|
|
{
|
|
useTuple = &i->second->getSource();
|
|
}
|
|
}
|
|
|
|
resip::Data& target = via.exists(p_maddr) ? via.param(p_maddr) : via.sentHost();
|
|
if (via.exists(p_received))
|
|
{
|
|
if (via.exists(p_rport))
|
|
{
|
|
uri.host() = via.param(p_received);
|
|
uri.port() = via.param(p_rport).port();
|
|
}
|
|
else
|
|
{
|
|
if (via.sentPort())
|
|
{
|
|
uri.host() = via.param(p_received);
|
|
uri.port() = via.sentPort();
|
|
}
|
|
else
|
|
{
|
|
uri.host() = via.param(p_received);
|
|
uri.port() = 5060; // !jf! bad
|
|
}
|
|
}
|
|
}
|
|
else if (via.exists(p_rport))
|
|
{
|
|
uri.host() = target;
|
|
uri.port() = via.param(p_rport).port();
|
|
}
|
|
else if (via.sentPort())
|
|
{
|
|
uri.host() = target;
|
|
uri.port() = via.sentPort();
|
|
}
|
|
else
|
|
{
|
|
uri.host() = target;
|
|
uri.port() = 5060;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// not request and not response
|
|
resip_assert(0);
|
|
}
|
|
|
|
DebugLog(<<"Target uri: " << uri);
|
|
|
|
// modifying the via
|
|
if (msg->isRequest())
|
|
{
|
|
resip_assert(!msg->header(h_Vias).empty());
|
|
msg->header(h_Vias).front().remove(p_maddr);
|
|
msg->header(h_Vias).front().transport() = Tuple::toData(mTransport->transport());
|
|
|
|
//Sufficient, and also necessary if we are sending on TLS.
|
|
if(msg->header(h_Vias).front().transport().lowercase() == "tls")
|
|
{
|
|
msg->header(h_Vias).front().sentHost() = mTransport->tlsDomain();
|
|
}
|
|
else if(mTransport->interfaceName()!="0.0.0.0" &&
|
|
!mTransport->interfaceName().empty())
|
|
{
|
|
msg->header(h_Vias).front().sentHost() = mTransport->interfaceName();
|
|
}
|
|
else
|
|
{
|
|
msg->header(h_Vias).front().sentHost() = nwIf;
|
|
}
|
|
msg->header(h_Vias).front().sentPort() = mTransport->port();
|
|
}
|
|
|
|
resip::Data encoded;
|
|
{
|
|
DataStream encodeStream(encoded);
|
|
msg->encode(encodeStream);
|
|
encodeStream.flush();
|
|
}
|
|
DebugLog (<< "encoded=" << encoded.c_str());
|
|
|
|
resip::Data toWrite = func(encoded);
|
|
|
|
if (useTuple)
|
|
{
|
|
// Find Transport via TransportDriver
|
|
Transport* transport = TransportDriver::instance().getClientTransport(useTuple->mTransportKey);
|
|
resip_assert(transport);
|
|
std::unique_ptr<SendData> toSend(transport->makeSendData(*useTuple, toWrite, "bogus"));
|
|
transport->send(std::move(toSend));
|
|
}
|
|
else
|
|
{
|
|
//The transport we are sending on had better match the transport we are sending to
|
|
uri.param(p_transport)=msg->header(h_Vias).front().transport();
|
|
DebugLog(<<"Trying to resolve...");
|
|
// send it over the transport
|
|
Resolver r(uri);
|
|
resip_assert (!r.mNextHops.empty());
|
|
DebugLog(<<"Resolved successfully.");
|
|
r.mNextHops.front().setTargetDomain(uri.host());
|
|
|
|
//Default TLS port
|
|
if(r.mNextHops.front().getType()==TLS && r.mNextHops.front().getPort()==5060)
|
|
{
|
|
r.mNextHops.front().setPort(5061);
|
|
}
|
|
std::unique_ptr<SendData> toSend(mTransport->makeSendData(r.mNextHops.front(), toWrite, "bogus"));
|
|
mTransport->send(std::move(toSend));
|
|
}
|
|
}
|
|
|
|
void TestSipEndPoint::storeSentInvite(const std::shared_ptr<SipMessage>& invite)
|
|
{
|
|
resip_assert(invite->isRequest());
|
|
resip_assert(invite->header(h_RequestLine).getMethod() == INVITE);
|
|
DebugLog (<< "Storing invite: " << invite->header(h_CallId) << " in " << this);
|
|
|
|
for(InviteList::iterator it = mInvitesSent.begin();
|
|
it != mInvitesSent.end(); it++)
|
|
{
|
|
if ( (*it)->header(h_CallId) == invite->header(h_CallId))
|
|
{
|
|
(*it) = invite;
|
|
return;
|
|
}
|
|
}
|
|
mInvitesSent.push_back(invite);
|
|
}
|
|
|
|
void TestSipEndPoint::storeReceivedInvite(const std::shared_ptr<SipMessage>& invite)
|
|
{
|
|
for(InviteList::iterator it = mInvitesReceived.begin();
|
|
it != mInvitesReceived.end(); it++)
|
|
{
|
|
if ( (*it)->header(h_CallId) == invite->header(h_CallId))
|
|
{
|
|
(*it) = invite;
|
|
return;
|
|
}
|
|
}
|
|
mInvitesReceived.push_back(invite);
|
|
}
|
|
|
|
|
|
void TestSipEndPoint::storeSentUpdate(const std::shared_ptr<SipMessage>& update)
|
|
{
|
|
resip_assert(update->isRequest());
|
|
resip_assert(update->header(h_RequestLine).getMethod() == UPDATE);
|
|
DebugLog (<< "Storing update: " << update->header(h_CallId) << " in " << this);
|
|
|
|
for(UpdateList::iterator it = mUpdatesSent.begin();
|
|
it != mUpdatesSent.end(); it++)
|
|
{
|
|
if ( (*it)->header(h_CallId) == update->header(h_CallId))
|
|
{
|
|
(*it) = update;
|
|
return;
|
|
}
|
|
}
|
|
mUpdatesSent.push_back(update);
|
|
}
|
|
|
|
void TestSipEndPoint::storeReceivedUpdate(const std::shared_ptr<SipMessage>& update)
|
|
{
|
|
for(UpdateList::iterator it = mUpdatesReceived.begin();
|
|
it != mUpdatesReceived.end(); it++)
|
|
{
|
|
if ( (*it)->header(h_CallId) == update->header(h_CallId))
|
|
{
|
|
(*it) = update;
|
|
return;
|
|
}
|
|
}
|
|
mUpdatesReceived.push_back(update);
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::getSentInvite(const CallId& callId)
|
|
{
|
|
for(InviteList::iterator it = mInvitesSent.begin();
|
|
it != mInvitesSent.end(); it++)
|
|
{
|
|
if ( (*it)->header(h_CallId) == callId)
|
|
{
|
|
return *it;
|
|
}
|
|
}
|
|
InfoLog (<< "No stored invites (probably retranmissions of failed test)");
|
|
InfoLog (<< Inserter(mInvitesSent));
|
|
throw AssertException("No stored invites (likely retranmissions from failed test)", __FILE__, __LINE__);
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::getReceivedInvite(const CallId& callId)
|
|
{
|
|
for(InviteList::iterator it = mInvitesReceived.begin();
|
|
it != mInvitesReceived.end(); it++)
|
|
{
|
|
if ( (*it)->header(h_CallId) == callId)
|
|
{
|
|
return *it;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::getReceivedUpdate(const CallId& callId)
|
|
{
|
|
for(UpdateList::iterator it = mUpdatesReceived.begin();
|
|
it != mUpdatesReceived.end(); it++)
|
|
{
|
|
if ( (*it)->header(h_CallId) == callId)
|
|
{
|
|
return *it;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void TestSipEndPoint::storeSentSubscribe(const std::shared_ptr<SipMessage>& subscribe)
|
|
{
|
|
InfoLog(<< "storeSentSubscribe " << *subscribe);
|
|
for (SentSubscribeList::iterator it = mSubscribesSent.begin();
|
|
it != mSubscribesSent.end(); ++it)
|
|
{
|
|
if (it->isMatch(subscribe))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
// add a new DialogSet
|
|
mSubscribesSent.push_back(::DialogSet(subscribe, *this));
|
|
}
|
|
|
|
void TestSipEndPoint::storeReceivedSubscribe(const std::shared_ptr<SipMessage>& subscribe)
|
|
{
|
|
for (ReceivedSubscribeList::iterator it = mSubscribesReceived.begin();
|
|
it != mSubscribesReceived.end(); ++it)
|
|
{
|
|
if ( (*it)->header(h_CallId) == subscribe->header(h_CallId))
|
|
{
|
|
(*it) = subscribe;
|
|
return;
|
|
}
|
|
}
|
|
mSubscribesReceived.push_back(subscribe);
|
|
}
|
|
|
|
void TestSipEndPoint::storeReceivedPublish(const std::shared_ptr<SipMessage>& publish)
|
|
{
|
|
for (ReceivedPublishList::iterator it = mPublishReceived.begin();
|
|
it != mPublishReceived.end(); ++it)
|
|
{
|
|
if ( (*it)->header(h_CallId) == publish->header(h_CallId))
|
|
{
|
|
(*it) = publish;
|
|
return;
|
|
}
|
|
}
|
|
mPublishReceived.push_back(publish);
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::getSentSubscribe(std::shared_ptr<SipMessage> msg)
|
|
{
|
|
InfoLog(<< "getSentSubscribe: " << *msg);
|
|
for (SentSubscribeList::iterator it = mSubscribesSent.begin();
|
|
it != mSubscribesSent.end(); ++it)
|
|
{
|
|
InfoLog(<< "getSentSubscribe trying " << *it->getMessage());
|
|
if (it->isMatch(msg))
|
|
{
|
|
return it->getMessage();
|
|
}
|
|
}
|
|
ErrLog(<< "getSentSubscribe failed");
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::getReceivedSubscribe(const CallId& callId)
|
|
{
|
|
for(ReceivedSubscribeList::iterator it = mSubscribesReceived.begin();
|
|
it != mSubscribesReceived.end(); it++)
|
|
{
|
|
if ( (*it)->header(h_CallId) == callId)
|
|
{
|
|
return *it;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::getReceivedPublish(const CallId& callId)
|
|
{
|
|
for(ReceivedSubscribeList::iterator it = mPublishReceived.begin();
|
|
it != mPublishReceived.end(); it++)
|
|
{
|
|
if ( (*it)->header(h_CallId) == callId)
|
|
{
|
|
return *it;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
DeprecatedDialog*
|
|
TestSipEndPoint::getDialog()
|
|
{
|
|
// An unfortunate "ONLY 1 dialog per endpoint" limitation
|
|
resip_assert(mDialogs.size() <= 1);
|
|
|
|
if (mDialogs.size())
|
|
{
|
|
return *(mDialogs.begin());
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
DeprecatedDialog*
|
|
TestSipEndPoint::getDialog(const CallId& callId,
|
|
const resip::Data& remoteTag)
|
|
{
|
|
DebugLog(<< "searching for callid: " << callId << " tag:" << remoteTag);
|
|
for(DialogList::iterator it = mDialogs.begin();
|
|
it != mDialogs.end(); it++)
|
|
{
|
|
DebugLog (<< "Comparing to dialog: " << (*it));
|
|
if ( (*it)->getCallId() == callId && (remoteTag.empty() || (*it)->getRemoteTag()==remoteTag))
|
|
{
|
|
DebugLog(<< "Dialog: " << *it << " " << (*it)->getCallId() << " "
|
|
<< (*it)->getRemoteTag() << " matched.");
|
|
return *it;
|
|
}
|
|
DebugLog(<< "Dialog: " << *it << " " << (*it)->getCallId() << " "
|
|
<< (*it)->getRemoteTag() << "did not match.");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DeprecatedDialog*
|
|
TestSipEndPoint::getDialog(const Uri& target)
|
|
{
|
|
// DebugLog(<< this->getContact() << " has " << mDialogs.size() << " dialogs.");
|
|
for(DialogList::iterator it = mDialogs.begin();
|
|
it != mDialogs.end(); it++)
|
|
{
|
|
// DebugLog(<< (*it)->getRemoteTarget().uri().getAor());
|
|
if ((*it)->getRemoteTarget().uri().getAor() == target.getAor())
|
|
{
|
|
// DebugLog(<< "Matched in getDialogByTarget");
|
|
return *it;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DeprecatedDialog*
|
|
TestSipEndPoint::getDialog(const Data& user)
|
|
{
|
|
DebugLog(<< this->getContact() << " has " << mDialogs.size() << " dialogs.");
|
|
for(DialogList::iterator it = mDialogs.begin();
|
|
it != mDialogs.end(); it++)
|
|
{
|
|
DebugLog(<< (*it)->getRemoteTarget().uri().user());
|
|
if ((*it)->getRemoteTarget().uri().user() == user)
|
|
{
|
|
DebugLog(<< "Matched in getDialog");
|
|
return *it;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DeprecatedDialog*
|
|
TestSipEndPoint::getDialog(const NameAddr& target)
|
|
{
|
|
return getDialog(target.uri());
|
|
}
|
|
|
|
// needs to deal with INVITE SDP contents
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::makeResponse(SipMessage& request, int responseCode)
|
|
{
|
|
resip_assert(request.isRequest());
|
|
if ( responseCode < 300 && responseCode > 100 &&
|
|
(request.header(h_RequestLine).getMethod() == INVITE ||
|
|
request.header(h_RequestLine).getMethod() == SUBSCRIBE ||
|
|
request.header(h_RequestLine).getMethod() == PUBLISH) )
|
|
{
|
|
DeprecatedDialog* dialog = getDialog(request.header(h_CallId),
|
|
request.header(h_From).param(p_tag));
|
|
if (!dialog)
|
|
{
|
|
DebugLog(<< "making a dialog, contact: " << getContact());
|
|
dialog = new DeprecatedDialog(getContact());
|
|
mDialogs.push_back(dialog);
|
|
DebugLog(<< "made a dialog (" << dialog << "), contact: " << getContact());
|
|
}
|
|
DebugLog(<< "Creating response using dialog: " << dialog);
|
|
return std::shared_ptr<SipMessage>(dialog->makeResponse(request, responseCode));
|
|
}
|
|
else
|
|
{
|
|
DeprecatedDialog* dialog = getDialog(request.header(h_CallId),
|
|
request.header(h_From).param(p_tag));
|
|
if (!dialog)
|
|
{
|
|
DebugLog(<<"making response outside of dialog, contact: " << getContact());
|
|
return std::shared_ptr<SipMessage>(Helper::makeResponse(request, responseCode, getContact()));
|
|
}
|
|
else
|
|
{
|
|
DebugLog(<< "Creating response using dialog: " << dialog);
|
|
return std::shared_ptr<SipMessage>(dialog->makeResponse(request, responseCode));
|
|
}
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Dump::go(std::shared_ptr<SipMessage> msg)
|
|
{
|
|
InfoLog(<<"##Dump: " << mEndPoint.getName() << " " << *msg);
|
|
// don't send it
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::ByeTo::go(std::shared_ptr<SipMessage> msg, const Uri& target)
|
|
{
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog(target);
|
|
resip_assert(dialog);
|
|
return std::shared_ptr<SipMessage>(dialog->makeBye());
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Bye::go(std::shared_ptr<SipMessage> msg)
|
|
{
|
|
resip::Data remoteTag(msg->isRequest() ? msg->header(h_From).param(p_tag) :
|
|
msg->header(h_To).param(p_tag) );
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog(msg->header(h_CallId),remoteTag);
|
|
if(!dialog)
|
|
{
|
|
resip::Data localTag(!msg->isRequest() ? msg->header(h_From).param(p_tag):
|
|
msg->header(h_To).param(p_tag) );
|
|
dialog=mEndPoint.getDialog(msg->header(h_CallId),localTag);
|
|
}
|
|
resip_assert(dialog);
|
|
return std::shared_ptr<SipMessage>(dialog->makeBye());
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Notify200To::go(std::shared_ptr<SipMessage> msg, const Uri& target)
|
|
{
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog(target);
|
|
resip_assert(dialog);
|
|
std::shared_ptr<SipMessage> notify(dialog->makeNotify());
|
|
notify->header(h_Event).value() = "refer";
|
|
SipFrag frag;
|
|
frag.message().header(h_StatusLine).responseCode() = 200;
|
|
frag.message().header(h_StatusLine).reason() = "OK";
|
|
notify->setContents(&frag);
|
|
return notify;
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Notify200::go(std::shared_ptr<SipMessage> msg)
|
|
{
|
|
resip::Data remoteTag(msg->isRequest() ? msg->header(h_From).param(p_tag) :
|
|
msg->header(h_To).param(p_tag) );
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog(msg->header(h_CallId),remoteTag);
|
|
resip_assert(dialog);
|
|
std::shared_ptr<SipMessage> notify(dialog->makeNotify());
|
|
notify->header(h_Event).value() = "refer";
|
|
SipFrag frag;
|
|
frag.message().header(h_StatusLine).responseCode() = 200;
|
|
frag.message().header(h_StatusLine).reason() = "OK";
|
|
notify->setContents(&frag);
|
|
return notify;
|
|
}
|
|
|
|
TestSipEndPoint::SipEndPointAction::SipEndPointAction(TestSipEndPoint* endPoint)
|
|
: mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::SipEndPointAction::operator()()
|
|
{
|
|
(*this)(*mEndPoint);
|
|
}
|
|
|
|
TestSipEndPoint::Refer::Refer(TestSipEndPoint* endPoint,
|
|
const resip::Uri& who,
|
|
const resip::Uri& to,
|
|
bool replaces)
|
|
: SipEndPointAction(endPoint),
|
|
mTo(to),
|
|
mWho(who),
|
|
mReplaces(replaces)
|
|
{
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::Refer::operator()(TestSipEndPoint& endPoint)
|
|
{
|
|
DeprecatedDialog* dialog = endPoint.getDialog(mWho.user());
|
|
resip_assert(dialog);
|
|
const std::shared_ptr<SipMessage> refer(dialog->makeRefer(NameAddr(mTo)));
|
|
if (mReplaces)
|
|
{
|
|
refer->header(h_Replaces) = dialog->makeReplaces();
|
|
}
|
|
endPoint.send(refer);
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::Refer::toString() const
|
|
{
|
|
return mEndPoint->getName() + ".refer()";
|
|
}
|
|
|
|
TestSipEndPoint::Refer*
|
|
TestSipEndPoint::refer(const resip::Uri& who,
|
|
const resip::Uri& to)
|
|
{
|
|
return new Refer(this, who, to);
|
|
}
|
|
|
|
TestSipEndPoint::Refer*
|
|
TestSipEndPoint::referReplaces(const resip::Uri& who,
|
|
const resip::Uri& to)
|
|
{
|
|
return new Refer(this, who, to, true);
|
|
}
|
|
|
|
TestSipEndPoint::ReInvite::ReInvite(TestSipEndPoint* from,
|
|
const resip::Uri& to,
|
|
bool matchUserOnly,
|
|
std::shared_ptr<resip::SdpContents> sdp)
|
|
: mEndPoint(*from),
|
|
mTo(to),
|
|
mMatchUserOnly(matchUserOnly),
|
|
mSdp(sdp)
|
|
{
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::ReInvite::operator()()
|
|
{
|
|
go();
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::ReInvite::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
go();
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::ReInvite::go()
|
|
{
|
|
DebugLog(<< "Re-Inviting to: " << mTo);
|
|
DeprecatedDialog* dialog;
|
|
if( mMatchUserOnly )
|
|
{
|
|
dialog = mEndPoint.getDialog(mTo.uri().user());
|
|
}
|
|
|
|
else
|
|
{
|
|
dialog = mEndPoint.getDialog(mTo);
|
|
}
|
|
|
|
if (!dialog)
|
|
{
|
|
InfoLog (<< "No matching dialog on " << mEndPoint.getName() << " for " << mTo);
|
|
throw AssertException(resip::Data("No matching dialog"), __FILE__, __LINE__);
|
|
}
|
|
|
|
const std::shared_ptr<SipMessage> invite(dialog->makeInvite());
|
|
if (mSdp)
|
|
{
|
|
invite->setContents(mSdp.get());
|
|
}
|
|
|
|
DebugLog(<< "TestSipEndPoint::ReInvite: " << *invite);
|
|
mEndPoint.storeSentInvite(invite);
|
|
mEndPoint.send(invite);
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::ReInvite::toString() const
|
|
{
|
|
return mEndPoint.getName() + ".reInvite()";
|
|
}
|
|
|
|
TestSipEndPoint::ReInvite*
|
|
TestSipEndPoint::reInvite(const TestSipEndPoint& endPoint)
|
|
{
|
|
return new ReInvite(this, endPoint.getContact().uri());
|
|
}
|
|
|
|
TestSipEndPoint::ReInvite*
|
|
TestSipEndPoint::reInvite(resip::Uri& url)
|
|
{
|
|
return new ReInvite(this, url);
|
|
}
|
|
|
|
TestSipEndPoint::ReInvite*
|
|
TestSipEndPoint::reInvite(const Data& user)
|
|
{
|
|
Uri to;
|
|
to.user() = user;
|
|
return new ReInvite(this, to, true);
|
|
}
|
|
|
|
TestSipEndPoint::ReInvite*
|
|
TestSipEndPoint::reInvite(const Data& user, const std::shared_ptr<resip::SdpContents>& sdp)
|
|
{
|
|
Uri to;
|
|
to.user() = user;
|
|
return new ReInvite(this, to, true, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::Update::Update(TestSipEndPoint* from,
|
|
const resip::Uri& to,
|
|
bool matchUserOnly,
|
|
std::shared_ptr<resip::SdpContents> sdp)
|
|
: mEndPoint(*from),
|
|
mTo(to),
|
|
mMatchUserOnly(matchUserOnly),
|
|
mSdp(sdp)
|
|
{
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::Update::operator()()
|
|
{
|
|
go();
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::Update::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
go();
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::Update::go()
|
|
{
|
|
DebugLog(<< "Update to: " << mTo);
|
|
DeprecatedDialog* dialog;
|
|
if( mMatchUserOnly )
|
|
{
|
|
dialog = mEndPoint.getDialog(mTo.uri().user());
|
|
}
|
|
|
|
else
|
|
{
|
|
dialog = mEndPoint.getDialog(mTo);
|
|
}
|
|
|
|
if (!dialog)
|
|
{
|
|
InfoLog (<< "No matching dialog on " << mEndPoint.getName() << " for " << mTo);
|
|
throw AssertException(resip::Data("No matching dialog"), __FILE__, __LINE__);
|
|
}
|
|
|
|
const std::shared_ptr<SipMessage> update(dialog->makeUpdate());
|
|
if (mSdp.get())
|
|
{
|
|
update->setContents(mSdp.get());
|
|
}
|
|
|
|
DebugLog(<< "TestSipEndPoint::Update: " << *update);
|
|
mEndPoint.storeSentUpdate(update);
|
|
mEndPoint.send(update);
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::Update::toString() const
|
|
{
|
|
return mEndPoint.getName() + ".Update()";
|
|
}
|
|
|
|
TestSipEndPoint::Update*
|
|
TestSipEndPoint::update(const TestSipEndPoint& endPoint)
|
|
{
|
|
return new Update(this, endPoint.getContact().uri());
|
|
}
|
|
|
|
TestSipEndPoint::Update*
|
|
TestSipEndPoint::update(const resip::Uri& url)
|
|
{
|
|
return new Update(this, url);
|
|
}
|
|
|
|
TestSipEndPoint::Update*
|
|
TestSipEndPoint::update(const Data& user)
|
|
{
|
|
Uri to;
|
|
to.user() = user;
|
|
return new Update(this, to, true);
|
|
}
|
|
|
|
TestSipEndPoint::Update*
|
|
TestSipEndPoint::update(const Data& user, const std::shared_ptr<resip::SdpContents>& sdp)
|
|
{
|
|
Uri to;
|
|
to.user() = user;
|
|
return new Update(this, to, true, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::InviteReferReplaces::InviteReferReplaces(TestSipEndPoint* from,
|
|
bool replaces)
|
|
: mEndPoint(*from), mReplaces(replaces)
|
|
{
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::InviteReferReplaces::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
SipEvent* sipEvent = dynamic_cast<SipEvent*>(event.get());
|
|
resip_assert(sipEvent);
|
|
const std::shared_ptr<SipMessage> refer = sipEvent->getMessage();
|
|
resip_assert(refer->isRequest());
|
|
resip_assert(refer->header(h_RequestLine).getMethod() == REFER);
|
|
|
|
const std::shared_ptr<SipMessage> invite(Helper::makeInvite(refer->header(h_ReferTo),
|
|
NameAddr(mEndPoint.getAddressOfRecord()),
|
|
mEndPoint.getContact()));
|
|
invite->header(h_ReferredBy) = refer->header(h_ReferredBy);
|
|
if (mReplaces)
|
|
{
|
|
invite->header(h_Replaces) = refer->header(h_Replaces);
|
|
}
|
|
mEndPoint.storeSentInvite(invite);
|
|
DebugLog(<< "sending INVITE " << invite->brief());
|
|
mEndPoint.send(invite);
|
|
}
|
|
resip::Data
|
|
TestSipEndPoint::InviteReferReplaces::toString() const
|
|
{
|
|
return mEndPoint.getName() + ".inviteReferReplaces()";
|
|
}
|
|
|
|
TestSipEndPoint::InviteReferReplaces*
|
|
TestSipEndPoint::inviteReferReplaces()
|
|
{
|
|
return new InviteReferReplaces(this, true);
|
|
}
|
|
|
|
TestSipEndPoint::InviteReferReplaces*
|
|
TestSipEndPoint::inviteReferredBy()
|
|
{
|
|
return new InviteReferReplaces(this, false);
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::IdentityMessageConditioner::operator()(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
return msg;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::IdentityRawConditioner::operator()(const resip::Data& input)
|
|
{
|
|
return input;
|
|
}
|
|
|
|
TestSipEndPoint::ChainConditions::ChainConditions(MessageConditionerFn fn1,
|
|
MessageConditionerFn fn2)
|
|
: mFn1(fn1),
|
|
mFn2(fn2)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::ChainConditions::operator()(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
msg = mFn2(msg);
|
|
return mFn1(msg);
|
|
}
|
|
|
|
TestSipEndPoint::ChainRawConditions::ChainRawConditions(RawConditionerFn fn1,
|
|
RawConditionerFn fn2)
|
|
: mFn1(std::move(fn1)),
|
|
mFn2(std::move(fn2))
|
|
{
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::ChainRawConditions::operator()(const resip::Data& input)
|
|
{
|
|
return mFn1(mFn2(input));
|
|
}
|
|
|
|
TestSipEndPoint::SaveMessage::SaveMessage(std::shared_ptr<resip::SipMessage>& msgPtr)
|
|
: mMsgPtr(msgPtr)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::SaveMessage::operator()(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
// .dlb. could snapshot here, but would slice (unless clone)
|
|
mMsgPtr = msg;
|
|
return msg;
|
|
}
|
|
|
|
TestSipEndPoint::MessageAction::MessageAction(TestSipEndPoint& from,
|
|
const resip::Uri& to)
|
|
: mEndPoint(from),
|
|
mTo(to),
|
|
mConditioner(TestSipEndPoint::identity),
|
|
mRawConditioner(TestSipEndPoint::raw_identity)
|
|
{
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::MessageAction::setConditioner(MessageConditionerFn conditioner)
|
|
{
|
|
mConditioner = ChainConditions(conditioner, mConditioner);
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::MessageAction::setRawConditioner(RawConditionerFn conditioner)
|
|
{
|
|
mRawConditioner = ChainRawConditions(conditioner, mRawConditioner);
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::MessageAction::operator()()
|
|
{
|
|
mMsg = go();
|
|
if (mMsg)
|
|
{
|
|
std::shared_ptr<SipMessage> conditioned(mConditioner(mMsg));
|
|
DebugLog(<< "sending: " << conditioned->brief());
|
|
mEndPoint.send(conditioned,mRawConditioner);
|
|
}
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::MessageAction::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
Action::operator()(event);
|
|
}
|
|
|
|
TestSipEndPoint::Invite::Invite(TestSipEndPoint* from,
|
|
const resip::Uri& to,
|
|
bool useOutbound,
|
|
EndpointReliableProvisionalMode mode,
|
|
std::shared_ptr<resip::SdpContents> sdp)
|
|
: MessageAction(*from, to),
|
|
mSdp(sdp),
|
|
mUseOutbound(useOutbound),
|
|
mRelProvMode(mode)
|
|
{}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Invite::go()
|
|
{
|
|
std::shared_ptr<SipMessage> invite(Helper::makeInvite(NameAddr(mTo),
|
|
NameAddr(mEndPoint.getAddressOfRecord()),
|
|
mEndPoint.getContact()));
|
|
if (mSdp)
|
|
invite->setContents(mSdp.get());
|
|
|
|
if(mUseOutbound)
|
|
{
|
|
invite->header(h_Contacts).front().uri().param(p_ob);
|
|
}
|
|
|
|
if(mRelProvMode == RelProvModeSupported)
|
|
{
|
|
invite->header(h_Supporteds).push_back(Token(Symbols::C100rel));
|
|
}
|
|
else if(mRelProvMode == RelProvModeRequired)
|
|
{
|
|
invite->header(h_Requires).push_back(Token(Symbols::C100rel));
|
|
}
|
|
|
|
// Add allow header
|
|
invite->header(h_Allows).push_back(Token(getMethodName(INVITE)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(ACK)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(CANCEL)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(OPTIONS)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(BYE)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(UPDATE)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(INFO)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(MESSAGE)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(REFER)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(PRACK)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(NOTIFY)));
|
|
invite->header(h_Allows).push_back(Token(getMethodName(SUBSCRIBE)));
|
|
|
|
mEndPoint.storeSentInvite(invite);
|
|
return invite;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::Invite::toString() const
|
|
{
|
|
return mEndPoint.getName() + ".invite()";
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::invite(const TestUser& endPoint, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, endPoint.getAddressOfRecord(), false, mode);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::invite(const TestUser& endPoint, const std::shared_ptr<resip::SdpContents>& sdp, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, endPoint.getAddressOfRecord(), false, mode, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::invite(const TestSipEndPoint& endPoint, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, endPoint.mAor, false, mode);
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::invite(const resip::Uri& url, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, url, false, mode);
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::invite(const resip::Uri& url, const std::shared_ptr<resip::SdpContents>& sdp, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, url, false, mode, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::invite(const resip::Data& url, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, resip::Uri(url), false, mode);
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::inviteWithOutbound(const TestUser& endPoint, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, endPoint.getAddressOfRecord(), true, mode);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::inviteWithOutbound(const TestUser& endPoint, const std::shared_ptr<resip::SdpContents>& sdp, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, endPoint.getAddressOfRecord(), true, mode, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::inviteWithOutbound(const TestSipEndPoint& endPoint, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, endPoint.mAor, true, mode);
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::inviteWithOutbound(const resip::Uri& url, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, url, true, mode);
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::inviteWithOutbound(const resip::Uri& url, const std::shared_ptr<resip::SdpContents>& sdp, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, url, true, mode, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::Invite*
|
|
TestSipEndPoint::inviteWithOutbound(const resip::Data& url, EndpointReliableProvisionalMode mode)
|
|
{
|
|
return new Invite(this, resip::Uri(url), true, mode);
|
|
}
|
|
|
|
TestSipEndPoint::SendSip::SendSip(TestSipEndPoint* from,
|
|
const resip::Uri& to,
|
|
std::shared_ptr<resip::SipMessage>& msg) :
|
|
MessageAction(*from,to),
|
|
mMsgToTransmit(msg)
|
|
{
|
|
}
|
|
|
|
Data
|
|
TestSipEndPoint::SendSip::toString() const
|
|
{
|
|
return Data("TestSipEndPoint::Send");
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::SendSip::go()
|
|
{
|
|
return mMsgToTransmit;
|
|
}
|
|
|
|
TestSipEndPoint::SendSip*
|
|
TestSipEndPoint::sendSip(std::shared_ptr<SipMessage>& msg,
|
|
const Uri& to)
|
|
{
|
|
return new SendSip(this,to,msg);
|
|
}
|
|
|
|
TestSipEndPoint::SendSip*
|
|
TestSipEndPoint::sendSip(std::shared_ptr<SipMessage>& msg,
|
|
const TestUser& endPoint)
|
|
{
|
|
return new SendSip(this,endPoint.getAddressOfRecord(),msg);
|
|
}
|
|
|
|
TestSipEndPoint::RawInvite::RawInvite(TestSipEndPoint* from,
|
|
const resip::Uri& to,
|
|
const resip::Data& rawText)
|
|
: MessageAction(*from, to),
|
|
mRawText(rawText)
|
|
{}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::RawInvite::go()
|
|
{
|
|
std::unique_ptr<SipMessage> msg(Helper::makeInvite(NameAddr(mTo),
|
|
NameAddr(mEndPoint.getAddressOfRecord()),
|
|
mEndPoint.getContact()));
|
|
std::shared_ptr<SipMessage> rawInvite = std::make_shared<SipRawMessage>(*msg, mRawText);
|
|
mEndPoint.storeSentInvite(rawInvite);
|
|
return rawInvite;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::RawInvite::toString() const
|
|
{
|
|
static const unsigned int truncate = 15;
|
|
resip::Data buffer;
|
|
{
|
|
DataStream strm(buffer);
|
|
strm << mEndPoint.getName() << ".rawInvite(\"" <<
|
|
((mRawText.size() <= truncate)
|
|
? mRawText
|
|
: resip::Data(mRawText.data(), truncate-2)) << "..\")";
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
TestSipEndPoint::RawInvite*
|
|
TestSipEndPoint::rawInvite(const TestUser& endPoint,
|
|
const resip::Data& rawText)
|
|
{
|
|
return new RawInvite(this, endPoint.getAddressOfRecord(), rawText);
|
|
}
|
|
|
|
TestSipEndPoint::RawInvite*
|
|
TestSipEndPoint::rawInvite(const TestSipEndPoint* endPoint,
|
|
const resip::Data& rawText)
|
|
{
|
|
return new RawInvite(this, endPoint->mAor, rawText);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::RawSend::RawSend(TestSipEndPoint* from,
|
|
const resip::Uri& to,
|
|
const resip::Data& rawText)
|
|
: mEndPoint(*from),
|
|
mTo(to),
|
|
mRawText(rawText),
|
|
mRawConditioner(TestSipEndPoint::raw_identity)
|
|
{}
|
|
|
|
void
|
|
TestSipEndPoint::RawSend::operator()()
|
|
{
|
|
go();
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::RawSend::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
go();
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::RawSend::go()
|
|
{
|
|
Tuple target(mTo.uri().host(), mTo.uri().port(), TCP);
|
|
mRawText=mRawConditioner(mRawText);
|
|
std::unique_ptr<SendData> toSend(mEndPoint.mTransport->makeSendData(target, mRawText, 0));
|
|
mEndPoint.mTransport->send(std::move(toSend));
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::RawSend::setRawConditioner(RawConditionerFn conditioner)
|
|
{
|
|
mRawConditioner = ChainRawConditions(conditioner, mRawConditioner);
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::RawSend::toString() const
|
|
{
|
|
static const unsigned int truncate = 15;
|
|
resip::Data buffer;
|
|
{
|
|
DataStream strm(buffer);
|
|
strm << mEndPoint.getName() << ".rawSend(\"" <<
|
|
((mRawText.size() <= truncate)
|
|
? mRawText
|
|
: resip::Data(mRawText.data(), truncate-2)) << "..\")";
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
TestSipEndPoint::RawSend*
|
|
TestSipEndPoint::rawSend(const TestUser& endPoint,
|
|
const resip::Data& rawText)
|
|
{
|
|
return new RawSend(this, endPoint.getAddressOfRecord(), rawText);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::RawSend*
|
|
TestSipEndPoint::rawSend(const TestSipEndPoint* endPoint,
|
|
const resip::Data& rawText)
|
|
{
|
|
return new RawSend(this, endPoint->mAor, rawText);
|
|
}
|
|
|
|
TestSipEndPoint::RawSend*
|
|
TestSipEndPoint::rawSend(const Uri& target, const resip::Data& rawText)
|
|
{
|
|
return new RawSend(this, target, rawText);
|
|
}
|
|
|
|
TestSipEndPoint::Subscribe::Subscribe(TestSipEndPoint* from, const Uri& to, const Token& eventPackage, int pExpires, const string PAssertedIdentity, bool pIgnoreExistingDialog)
|
|
: MessageAction(*from, to),
|
|
mEventPackage(eventPackage),
|
|
mAccept(),
|
|
mExpires(pExpires),
|
|
mIgnoreExistingDialog(pIgnoreExistingDialog)
|
|
{
|
|
if (PAssertedIdentity.size() != 0)
|
|
mPAssertedIdentity = PAssertedIdentity;
|
|
}
|
|
|
|
TestSipEndPoint::Subscribe::Subscribe(TestSipEndPoint* from,
|
|
const Uri& to,
|
|
const Token& eventPackage,
|
|
const Mime& accept,
|
|
std::shared_ptr<resip::Contents> contents)
|
|
: MessageAction(*from, to),
|
|
mEventPackage(eventPackage),
|
|
mAccept(accept),
|
|
mContents(contents),
|
|
mExpires(3600),
|
|
mIgnoreExistingDialog(false)
|
|
{
|
|
}
|
|
|
|
TestSipEndPoint::Subscribe::Subscribe(TestSipEndPoint* from,
|
|
const Uri& to,
|
|
const Token& eventPackage,
|
|
const string allow,
|
|
const string supported,
|
|
const int mExpires,
|
|
const string PAssertedIdentity
|
|
)
|
|
|
|
: MessageAction(*from, to),
|
|
mEventPackage(eventPackage),
|
|
mAllow(allow),
|
|
mSupported(supported),
|
|
mExpires(mExpires),
|
|
mPAssertedIdentity(PAssertedIdentity),
|
|
mIgnoreExistingDialog(false)
|
|
{
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::Subscribe::toString() const
|
|
{
|
|
return mEndPoint.getName() + ".subscribe()";
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::Subscribe::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
if (! mEndPoint.getDialog())
|
|
{
|
|
// subscribe creating a dialog from an incoming request, as opposed to the normal 1xx, 2xx response to INVITE.
|
|
// The test we want to achieve is:
|
|
// --INV-->, <--SUB--, <--1xx--, <--2xx--, --ACK-->, --200(SUB)-->, etc...
|
|
SipEvent* sipEvent = dynamic_cast<SipEvent*>(event.get());
|
|
if (sipEvent)
|
|
{
|
|
std::shared_ptr<SipMessage> request = sipEvent->getMessage();
|
|
if (request && request->isRequest())
|
|
{
|
|
// Create the dialog by making a dummy response.
|
|
std::shared_ptr<SipMessage> dummy = mEndPoint.makeResponse(*request, 180);
|
|
}
|
|
}
|
|
}
|
|
MessageAction::operator()(event);
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Subscribe::go()
|
|
{
|
|
std::shared_ptr<SipMessage> subscribe;
|
|
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog();
|
|
if (dialog && !mIgnoreExistingDialog)
|
|
{
|
|
subscribe = std::shared_ptr<SipMessage>(dialog->makeRequest(SUBSCRIBE));
|
|
}
|
|
else
|
|
{
|
|
subscribe = std::shared_ptr<SipMessage>(Helper::makeRequest(NameAddr(mTo),
|
|
NameAddr(mEndPoint.getAddressOfRecord()),
|
|
mEndPoint.getContact(),
|
|
SUBSCRIBE));
|
|
}
|
|
|
|
// subscribe->header(h_Expires).value() = 3600;
|
|
subscribe->header(h_Expires).value() = mExpires;
|
|
|
|
subscribe->header(h_Event) = mEventPackage;
|
|
if( !mAccept.type().empty() )
|
|
subscribe->header(h_Accepts).push_front(mAccept);
|
|
if( mContents.get() )
|
|
subscribe->setContents(mContents.get());
|
|
|
|
if (mAllow.length() != 0)
|
|
{
|
|
resip::Data AllowData(mAllow);
|
|
resip::Token AllowToken(AllowData);
|
|
subscribe->header(h_Allows).push_back(AllowToken);
|
|
}
|
|
if (mSupported.length() != 0)
|
|
{
|
|
resip::Data SupportedData(mSupported);
|
|
resip::Token SupportedToken(SupportedData);
|
|
subscribe->header(h_Supporteds).push_back(SupportedToken);
|
|
}
|
|
if (mPAssertedIdentity.length() != 0)
|
|
{
|
|
resip::Data PAssertedId(mPAssertedIdentity);
|
|
NameAddr PAssertedId_NameAddr(PAssertedId);
|
|
subscribe->header(h_PAssertedIdentities).push_back(PAssertedId_NameAddr);
|
|
}
|
|
|
|
mEndPoint.storeSentSubscribe(subscribe);
|
|
DebugLog(<< "sending SUBSCRIBE " << subscribe->brief());
|
|
|
|
return subscribe;
|
|
}
|
|
|
|
TestSipEndPoint::Subscribe*
|
|
TestSipEndPoint::subscribe(const TestSipEndPoint* endPoint, const resip::Token& eventPackage)
|
|
{
|
|
return new Subscribe(this, endPoint->mAor, eventPackage);
|
|
}
|
|
|
|
TestSipEndPoint::Subscribe*
|
|
TestSipEndPoint::subscribe(const TestUser& endPoint, const resip::Token& eventPackage)
|
|
{
|
|
return new Subscribe(this, endPoint.getAddressOfRecord(), eventPackage);
|
|
}
|
|
|
|
TestSipEndPoint::Subscribe*
|
|
TestSipEndPoint::subscribe(const Uri& url, const Token& eventPackage, const Mime& accept, const std::shared_ptr<resip::Contents>& contents)
|
|
{
|
|
return new Subscribe(this, url, eventPackage, accept, contents);
|
|
}
|
|
|
|
TestSipEndPoint::Subscribe*
|
|
TestSipEndPoint::subscribe(const Uri& url, const Token& eventPackage,
|
|
const int pExpires,
|
|
const string PAssertedIdentity,
|
|
bool pIgnoreExistingDialog)
|
|
{
|
|
return new Subscribe(this, url, eventPackage, pExpires, PAssertedIdentity,
|
|
pIgnoreExistingDialog);
|
|
}
|
|
|
|
TestSipEndPoint::Subscribe*
|
|
TestSipEndPoint::subscribe(const Uri& url, const Token& eventPackage,
|
|
const string allow,
|
|
const string supported,
|
|
const int pExpires,
|
|
const string PAssertedIdentity)
|
|
{
|
|
return new Subscribe(this, url, eventPackage,
|
|
allow, supported, pExpires, PAssertedIdentity);
|
|
}
|
|
|
|
TestSipEndPoint::Request::Request(TestSipEndPoint* from,
|
|
const resip::Uri& to,
|
|
resip::MethodTypes type,
|
|
std::shared_ptr<resip::Contents> contents)
|
|
: MessageAction(*from, to),
|
|
mType(type),
|
|
mContents(contents)
|
|
{}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::Request::toString() const
|
|
{
|
|
resip::Data buffer;
|
|
{
|
|
DataStream strm(buffer);
|
|
strm << mEndPoint.getName() << "." << getMethodName(mType) << "(" << mTo << ")";
|
|
strm.flush();
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Request::go()
|
|
{
|
|
// !jf! this really should be passed in a dialog-id to identify which dialog
|
|
// to use
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog();
|
|
if (dialog)
|
|
{
|
|
std::shared_ptr<SipMessage> request(dialog->makeRequest(mType));
|
|
if (mContents.get() != 0) request->setContents(mContents.get());
|
|
request->header(h_Expires).value() = 3600;
|
|
return request;
|
|
}
|
|
else
|
|
{
|
|
std::shared_ptr<SipMessage> request(Helper::makeRequest(NameAddr(mTo),
|
|
NameAddr(mEndPoint.getAddressOfRecord()),
|
|
mEndPoint.getContact(),
|
|
mType));
|
|
if (mContents != 0) request->setContents(mContents.get());
|
|
request->header(h_Expires).value() = 3600;
|
|
return request;
|
|
}
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::request(const TestUser& endPoint, resip::MethodTypes method,
|
|
std::shared_ptr<resip::Contents> contents)
|
|
{
|
|
return new Request(this, endPoint.getAddressOfRecord(), method, contents);
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::request(const resip::Uri& to, resip::MethodTypes method,
|
|
std::shared_ptr<resip::Contents> contents)
|
|
{
|
|
return new Request(this, to, method, contents);
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::info(const TestSipEndPoint* endPoint)
|
|
{
|
|
return new Request(this, endPoint->mAor, resip::INFO);
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::info(const TestUser& endPoint)
|
|
{
|
|
return new Request(this, endPoint.getAddressOfRecord(), resip::INFO);
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::info(const Uri& url)
|
|
{
|
|
return new Request(this, url, resip::INFO);
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::info(const Uri& url, std::shared_ptr<resip::Contents> contents)
|
|
{
|
|
return new Request(this, url, resip::INFO, contents);
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::message(const TestSipEndPoint* endPoint, const Data& text)
|
|
{
|
|
auto plain = std::make_shared<PlainContents>();
|
|
plain->text() = text;
|
|
return new Request(this, endPoint->mAor, resip::MESSAGE, plain);
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::message(const TestUser& endPoint, const Data& text)
|
|
{
|
|
auto plain = std::make_shared<PlainContents>();
|
|
plain->text() = text;
|
|
return new Request(this, endPoint.getAddressOfRecord(), resip::MESSAGE, plain);
|
|
}
|
|
|
|
// vk
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::message(const NameAddr& target, const Data& text, const messageType contentType)
|
|
{
|
|
if (contentType == messageCpim)
|
|
{
|
|
auto cpim = std::make_shared<CpimContents>();
|
|
cpim->text() = text;
|
|
return new Request(this, target.uri(), resip::MESSAGE, cpim);
|
|
}
|
|
else // if (contentType == textPlain)
|
|
{
|
|
auto plain = std::make_shared<PlainContents>();
|
|
plain->text() = text;
|
|
return new Request(this, target.uri(), resip::MESSAGE, plain);
|
|
}
|
|
}
|
|
// end - vk
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::message(const resip::Uri& target, const Data& text)
|
|
{
|
|
auto plain = std::make_shared<PlainContents>();
|
|
plain->text() = text;
|
|
return new Request(this, target, resip::MESSAGE, plain);
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::message(const resip::Uri& target, std::shared_ptr<resip::Contents> contents)
|
|
{
|
|
return new Request(this, target, resip::MESSAGE, contents);
|
|
}
|
|
|
|
// vk
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::options(const Uri& url)
|
|
{
|
|
return new Request(this, url, resip::OPTIONS);
|
|
}
|
|
|
|
TestSipEndPoint::Publish::Publish(TestSipEndPoint* from, const resip::Uri& to,
|
|
const resip::Token& eventPackage,
|
|
std::shared_ptr<resip::Contents> contents,
|
|
int pExpires,
|
|
const std::string PAssertedIdentity,
|
|
const std::string pSIPIfEtag)
|
|
: MessageAction(*from, to),
|
|
mType(resip::PUBLISH),
|
|
mContents(contents),
|
|
mEventPackage(eventPackage),
|
|
mExpires(pExpires),
|
|
mPAssertedIdentity(PAssertedIdentity),
|
|
mSIPIfEtag(pSIPIfEtag)
|
|
{}
|
|
|
|
TestSipEndPoint::Publish::Publish(TestSipEndPoint* from,
|
|
const resip::Uri& to,
|
|
resip::MethodTypes type,
|
|
std::shared_ptr<resip::Contents> contents)
|
|
: MessageAction(*from, to),
|
|
mType(type),
|
|
mContents(contents)
|
|
{}
|
|
|
|
|
|
TestSipEndPoint::Publish*
|
|
TestSipEndPoint::publish(const Uri& url, const Token& eventPackage,
|
|
const int pExpires, const string PAssertedIdentity,
|
|
const string publishBody, const string pSIPIfEtag)
|
|
{
|
|
/*
|
|
WHAT PREVIOUSLY WORKED BUT NOW CORES...
|
|
Data text(publishBody);
|
|
HeaderFieldValue hfv(text.data(), text.size());
|
|
Mime type("application", "pidf+xml");
|
|
Pidf pc(&hfv, type);
|
|
std::shared_ptr<resip::Contents> body(&pc);
|
|
|
|
....
|
|
WHAT NOW NEEDS TO BE DONE INSTEAD..
|
|
*/
|
|
Data* text = new Data(publishBody);
|
|
HeaderFieldValue hfv(text->data(), text->size());
|
|
Mime type("application", "pidf+xml");
|
|
auto pc = std::make_shared<GenericPidfContents>(hfv, type);
|
|
/*
|
|
*/
|
|
|
|
Publish* localPublish = new Publish(this, url, eventPackage,
|
|
pc, pExpires, PAssertedIdentity,
|
|
pSIPIfEtag);
|
|
|
|
DebugLog(<< "1. START OF MESSAGE" );
|
|
DebugLog(<< localPublish->toString() );
|
|
DebugLog(<< endl << "1. END OF MESSAGE" );
|
|
|
|
return localPublish ;
|
|
}
|
|
|
|
TestSipEndPoint::Publish*
|
|
TestSipEndPoint::publish(const resip::NameAddr& target, const resip::Data& text)
|
|
{
|
|
HeaderFieldValue hfv(text.data(), text.size());
|
|
Mime type("application", "pidf+xml");
|
|
auto pc = std::make_shared<GenericPidfContents>(hfv, type);
|
|
|
|
return new Publish(this, target.uri(), resip::PUBLISH, pc);
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::Publish::toString() const
|
|
{
|
|
resip::Data buffer;
|
|
{
|
|
DataStream strm(buffer);
|
|
strm << mEndPoint.getName() << "." << getMethodName(mType) << "(" << mTo << ")";
|
|
strm.flush();
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Publish::go()
|
|
{
|
|
#if 0
|
|
PUBLISH SHOULD NEVER OCCUR INSIDE A DIALOG. PERIOD END OF STORY.
|
|
|
|
// !jf! this really should be passed in a dialog-id to identify which dialog
|
|
// to use
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog();
|
|
if (dialog)
|
|
{
|
|
std::shared_ptr<SipMessage> request(dialog->makeRequest(mType));
|
|
if (mContents) request->setContents(mContents.get());
|
|
request->header(h_Expires).value() = 3600;
|
|
|
|
/*
|
|
TEMPORARILY INTRODUCED AS A PATCH JOB TO INVESTIGATE SOMETHING
|
|
|
|
request->header(h_Expires).value() = mExpires;
|
|
request->header(h_Event) = mEventPackage ;
|
|
request->header(h_From).uri() = request->header(h_To).uri();
|
|
request->header(h_Contacts).clear();
|
|
|
|
if (mPAssertedIdentity.size() != 0)
|
|
{
|
|
resip::Data PAssertedId(mPAssertedIdentity);
|
|
NameAddr PAssertedId_NameAddr(PAssertedId);
|
|
request->header(h_PAssertedIdentities).push_back(PAssertedId_NameAddr);
|
|
}
|
|
END OF TEMP INTRODUCITON - DELETE THIS SECTION JUST AS SOON AS YOU CAN
|
|
*/
|
|
return request;
|
|
}
|
|
else
|
|
{
|
|
#endif // 0
|
|
std::shared_ptr<SipMessage> request(Helper::makeRequest(NameAddr(mTo),
|
|
NameAddr(mEndPoint.getAddressOfRecord()),
|
|
mEndPoint.getContact(),
|
|
mType));
|
|
|
|
request->header(h_Expires).value() = mExpires;
|
|
request->header(h_Event) = mEventPackage ;
|
|
request->header(h_From).uri() = request->header(h_To).uri();
|
|
request->header(h_Contacts).clear();
|
|
|
|
if (mPAssertedIdentity.size() != 0)
|
|
{
|
|
resip::Data PAssertedId(mPAssertedIdentity);
|
|
NameAddr PAssertedId_NameAddr(PAssertedId);
|
|
request->header(h_PAssertedIdentities).push_back(PAssertedId_NameAddr);
|
|
}
|
|
|
|
DebugLog(<< "2. START OF MESSAGE" );
|
|
DebugLog(<< *request );
|
|
DebugLog(<< "2. END OF MESSAGE" );
|
|
if (mContents) request->setContents(mContents.get());
|
|
DebugLog(<< "3. START OF MESSAGE" );
|
|
DebugLog(<< *request );
|
|
DebugLog(<< "3. END OF MESSAGE" );
|
|
// request->header(h_Expires).value() = 3600;
|
|
return request;
|
|
#if 0
|
|
}
|
|
#endif // 0
|
|
}
|
|
|
|
/*
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::publish(const Uri& url, const Token& eventPackage,
|
|
const int pExpires, const string PAssertedIdentity,
|
|
const string publishBody)
|
|
{
|
|
Data text(publishBody);
|
|
HeaderFieldValue hfv(text.data(), text.size());
|
|
Mime type("application", "pidf+xml");
|
|
Pidf pc(&hfv, type);
|
|
std::shared_ptr<resip::Contents> body(&pc);
|
|
|
|
Request* localPublish = new Request(this, url, resip::PUBLISH, body);
|
|
// TODO: Get these in...
|
|
// localPublish->mMsg->header(h_Event) = eventPackage;
|
|
// localPublish->mMsg->header(h_Expires) = pExpires;
|
|
return localPublish ;
|
|
}
|
|
|
|
TestSipEndPoint::Request*
|
|
TestSipEndPoint::publish(const resip::NameAddr& target, const resip::Data& text)
|
|
{
|
|
HeaderFieldValue hfv(text.data(), text.size());
|
|
Mime type("application", "pidf+xml");
|
|
Pidf pc(&hfv, type);
|
|
|
|
|
|
std::shared_ptr<resip::Contents> body(&pc);
|
|
return new Request(this, target.uri(), resip::PUBLISH, body);
|
|
}
|
|
*/
|
|
// end - vk
|
|
|
|
TestSipEndPoint::Retransmit::Retransmit(TestSipEndPoint& endPoint,
|
|
std::shared_ptr<resip::SipMessage>& msg)
|
|
: MessageExpectAction(endPoint),
|
|
mMsgToRetransmit(msg)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Retransmit::go(std::shared_ptr<resip::SipMessage>)
|
|
{
|
|
return mMsgToRetransmit;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::Retransmit::toString() const
|
|
{
|
|
return mEndPoint.getName() + ".retransmit()";
|
|
}
|
|
|
|
TestSipEndPoint::Retransmit*
|
|
TestSipEndPoint::retransmit(std::shared_ptr<resip::SipMessage>& msg)
|
|
{
|
|
return new Retransmit(*this, msg);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::CloseTransport::CloseTransport(TestSipEndPoint* endPoint)
|
|
: mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::CloseTransport::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
operator()();
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::CloseTransport::operator()()
|
|
{
|
|
resip_assert(dynamic_cast<UdpTransport*>(mEndPoint->mTransport) == 0);
|
|
|
|
InfoLog(<< mEndPoint->getName() << " closing transport");
|
|
|
|
// !dlb! assert(endpoint->hasOwnTransport());
|
|
mEndPoint->unregisterFromTransportDriver();
|
|
delete mEndPoint->mTransport;
|
|
mEndPoint->mTransport = 0;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::CloseTransport::toString() const
|
|
{
|
|
return mEndPoint->getName() + ".closeTransport()";
|
|
}
|
|
|
|
TestSipEndPoint::CloseTransport*
|
|
TestSipEndPoint::closeTransport()
|
|
{
|
|
// make sure the transport is not connectionless
|
|
resip_assert(dynamic_cast<UdpTransport*>(mTransport) == 0);
|
|
return new CloseTransport(this);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::MessageExpectAction::MessageExpectAction(TestSipEndPoint& from)
|
|
: mEndPoint(from),
|
|
mMsg(),
|
|
mConditioner(TestSipEndPoint::identity),
|
|
mRawConditioner(TestSipEndPoint::raw_identity)
|
|
{
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::MessageExpectAction::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
SipEvent* sipEvent = dynamic_cast<SipEvent*>(event.get());
|
|
|
|
if (!sipEvent && !mEndPoint.mLastMessage)
|
|
{
|
|
//!dcm! use last message received if available--may want to have an option
|
|
//to turn off this facility
|
|
ErrLog(<< "a TestSipEndPoint action requires a SipEvent!");
|
|
throw AssertException("requires a SipEvent", __FILE__, __LINE__);
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage> msg = sipEvent ? sipEvent->getMessage() : mEndPoint.mLastMessage;
|
|
|
|
mMsg = go(msg);
|
|
mConditioner(mMsg);
|
|
if (mMsg != 0)
|
|
{
|
|
DebugLog(<< "sending: " << mMsg->brief());
|
|
mEndPoint.send(mMsg,mRawConditioner);
|
|
}
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::MessageExpectAction::setConditioner(MessageConditionerFn conditioner)
|
|
{
|
|
mConditioner = ChainConditions(conditioner, mConditioner);
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::MessageExpectAction::setRawConditioner(RawConditionerFn conditioner)
|
|
{
|
|
mRawConditioner = ChainRawConditions(conditioner, mRawConditioner);
|
|
}
|
|
|
|
TestSipEndPoint::RawReply::RawReply(TestSipEndPoint& from,
|
|
const resip::Data& rawText)
|
|
: MessageExpectAction(from),
|
|
mRawText(rawText)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::RawReply::go(std::shared_ptr<SipMessage> msg)
|
|
{
|
|
// set via, from, to off msg?
|
|
std::shared_ptr<SipMessage> mmsg(SipMessage::make(mRawText));
|
|
return mmsg;
|
|
}
|
|
|
|
TestSipEndPoint::Send300::Send300(TestSipEndPoint & endpoint, std::set<resip::NameAddr> alternates)
|
|
: MessageExpectAction(endpoint),
|
|
mAlternates(alternates),
|
|
mEndpoint(endpoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send300::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
std::shared_ptr<resip::SipMessage> response = mEndpoint.makeResponse(*msg, 300);
|
|
while(!response->header(h_Contacts).empty())
|
|
{
|
|
response->header(h_Contacts).pop_front();
|
|
}
|
|
for(std::set<resip::NameAddr>::const_iterator i=mAlternates.begin();i!=mAlternates.end();++i)
|
|
{
|
|
response->header(h_Contacts).push_back(*i);
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send300(std::set<resip::NameAddr> alternates)
|
|
{
|
|
return new Send300(*this,alternates);
|
|
}
|
|
|
|
// vk
|
|
|
|
// 301
|
|
|
|
TestSipEndPoint::Send301::Send301(TestSipEndPoint & endPoint, std::set<resip::NameAddr> alternates)
|
|
: MessageExpectAction(endPoint),
|
|
mAlternates(alternates),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send301::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
return mEndPoint.makeResponse(*msg, 301);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send301(std::set<resip::NameAddr> alternates)
|
|
{
|
|
return new Send301(*this, alternates);
|
|
}
|
|
|
|
// 400
|
|
|
|
TestSipEndPoint::Send400::Send400(TestSipEndPoint & endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send400::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
return mEndPoint.makeResponse(*msg, 400);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send400()
|
|
{
|
|
return new Send400(*this);
|
|
}
|
|
|
|
// 407
|
|
|
|
TestSipEndPoint::Send407::Send407(TestSipEndPoint & endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send407::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
return mEndPoint.makeResponse(*msg, 407);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send407()
|
|
{
|
|
return new Send407(*this);
|
|
}
|
|
|
|
// 408
|
|
|
|
TestSipEndPoint::Send408::Send408(TestSipEndPoint & endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send408::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
return mEndPoint.makeResponse(*msg, 408);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send408()
|
|
{
|
|
return new Send408(*this);
|
|
}
|
|
|
|
// 410
|
|
|
|
TestSipEndPoint::Send410::Send410(TestSipEndPoint & endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send410::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
return mEndPoint.makeResponse(*msg, 410);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send410()
|
|
{
|
|
return new Send410(*this);
|
|
}
|
|
|
|
// 482
|
|
|
|
TestSipEndPoint::Send482::Send482(TestSipEndPoint & endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send482::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
return mEndPoint.makeResponse(*msg, 482);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send482()
|
|
{
|
|
return new Send482(*this);
|
|
}
|
|
|
|
// 483
|
|
|
|
TestSipEndPoint::Send483::Send483(TestSipEndPoint & endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send483::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
return mEndPoint.makeResponse(*msg, 483);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send483()
|
|
{
|
|
return new Send483(*this);
|
|
}
|
|
|
|
|
|
// 500
|
|
|
|
TestSipEndPoint::Send500WithRetryAfter::Send500WithRetryAfter(TestSipEndPoint & endPoint, int retryAfter)
|
|
: MessageExpectAction(endPoint),
|
|
mRetryAfter(retryAfter),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send500WithRetryAfter::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*msg, 500);
|
|
response->header(h_RetryAfter).value() = mRetryAfter;
|
|
// response->header(h_RetryAfter).comment() = "Service Unavailable";
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send500WithRetryAfter(int retryAfter)
|
|
{
|
|
return new Send500WithRetryAfter(*this, retryAfter);
|
|
}
|
|
|
|
|
|
// 503
|
|
|
|
TestSipEndPoint::Send503WithRetryAfter::Send503WithRetryAfter(TestSipEndPoint & endPoint, int retryAfter)
|
|
: MessageExpectAction(endPoint),
|
|
mRetryAfter(retryAfter),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send503WithRetryAfter::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*msg, 503);
|
|
response->header(h_RetryAfter).value() = mRetryAfter;
|
|
// response->header(h_RetryAfter).comment() = "Service Unavailable";
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send503WithRetryAfter(int retryAfter)
|
|
{
|
|
return new Send503WithRetryAfter(*this, retryAfter);
|
|
}
|
|
|
|
// end - vk
|
|
|
|
TestSipEndPoint::Send302::Send302(TestSipEndPoint & endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
TestSipEndPoint::Send302::Send302(TestSipEndPoint& endPoint, const resip::Uri& redirectTo)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mRedirectTo(new resip::Uri(redirectTo))
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send302::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
resip_assert (msg->isRequest());
|
|
std::shared_ptr<resip::SipMessage> resp = mEndPoint.makeResponse(*msg, 302);
|
|
if (mRedirectTo)
|
|
{
|
|
resp->header(h_Contacts).clear();
|
|
resp->header(h_Contacts).push_back(NameAddr(*mRedirectTo));
|
|
}
|
|
return resp;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send302()
|
|
{
|
|
return new Send302(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send302(const resip::Uri& redirectTarget)
|
|
{
|
|
return new Send302(*this, redirectTarget);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::Send202ToSubscribe::Send202ToSubscribe(TestSipEndPoint & endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send202ToSubscribe::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> subscribe;
|
|
subscribe = mEndPoint.getReceivedSubscribe(msg->header(resip::h_CallId));
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*subscribe, 202);
|
|
|
|
if (subscribe->exists(h_Expires))
|
|
{
|
|
response->header(h_Expires).value() = subscribe->header(h_Expires).value();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send202ToSubscribe()
|
|
{
|
|
return new Send202ToSubscribe(*this);
|
|
}
|
|
|
|
TestSipEndPoint::Send200ToPublish::Send200ToPublish(TestSipEndPoint& endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send200ToPublish::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> publish;
|
|
publish = mEndPoint.getReceivedPublish(msg->header(resip::h_CallId));
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*publish, 200);
|
|
|
|
if (publish->exists(h_Expires))
|
|
{
|
|
response->header(h_Expires).value() = publish->header(h_Expires).value();
|
|
}
|
|
|
|
response->header(h_SIPETag).value() = Data(resip::Random::getRandom());
|
|
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send200ToPublish()
|
|
{
|
|
return new Send200ToPublish(*this);
|
|
}
|
|
|
|
TestSipEndPoint::Send423Or200ToPublish::Send423Or200ToPublish(TestSipEndPoint& endPoint, int minExpires)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mMinExpires(minExpires)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send423Or200ToPublish::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> publish;
|
|
publish = mEndPoint.getReceivedPublish(msg->header(resip::h_CallId));
|
|
std::shared_ptr<resip::SipMessage> response;
|
|
|
|
resip_assert(publish->exists(h_Expires));
|
|
|
|
if (publish->header(h_Expires).value() < mMinExpires)
|
|
{
|
|
response = mEndPoint.makeResponse(*publish, 423);
|
|
response->header(h_MinExpires).value() = mMinExpires;
|
|
}
|
|
else
|
|
{
|
|
response = mEndPoint.makeResponse(*publish, 200);
|
|
response->header(h_SIPETag).value() = Data(resip::Random::getRandom());
|
|
response->header(h_Expires).value() = publish->header(h_Expires).value();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send423Or200ToPublish(int minExpires)
|
|
{
|
|
return new Send423Or200ToPublish(*this, minExpires);
|
|
}
|
|
|
|
TestSipEndPoint::Send401::Send401(TestSipEndPoint& endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send401::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> response(mEndPoint.makeResponse(*msg, 401));
|
|
|
|
Auth auth;
|
|
auth.scheme() = "Digest";
|
|
auth.param(p_nonce) = resip::Random::getCryptoRandomHex(8);
|
|
auth.param(p_algorithm) = "MD5";
|
|
auth.param(p_realm) = "localhost";
|
|
auth.param(p_qopOptions) = "auth";
|
|
auth.param(p_opaque) = "0000000000000000";
|
|
|
|
response->header(h_WWWAuthenticates).push_back(auth);
|
|
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::Send200ToRegister::Send200ToRegister(TestSipEndPoint& endPoint, const NameAddr& contact) :
|
|
MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mUseContact(true),
|
|
mContact(contact)
|
|
{}
|
|
|
|
TestSipEndPoint::Send200ToRegister::Send200ToRegister(TestSipEndPoint& endPoint) :
|
|
MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mUseContact(false),
|
|
mContact()
|
|
{}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send200ToRegister::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*msg, 200);
|
|
|
|
response->remove(h_Contacts);
|
|
|
|
// check whether we need to remove bindings
|
|
bool bExpires = false;
|
|
if( msg->header(h_Contacts).front().exists(p_expires) && msg->header(h_Contacts).front().param(p_expires) == 0 )
|
|
bExpires = true;
|
|
if( ! bExpires && msg->exists(h_Expires) && msg->header(h_Expires).value() == 0 )
|
|
bExpires = true;
|
|
|
|
if( !bExpires )
|
|
{
|
|
response->header(h_Contacts).push_back(msg->header(h_Contacts).front());
|
|
response->header(h_Contacts).front().param(p_expires) = 3600;
|
|
}
|
|
|
|
// rport already in Via header, add received
|
|
response->header(h_Vias).front().param(p_received) = msg->header(h_Contacts).front().uri().host();
|
|
|
|
// add rport and received to via
|
|
if( mUseContact )
|
|
{
|
|
if (! mContact.uri().host().empty())
|
|
response->header(h_Vias).front().param(p_received) = mContact.uri().host();
|
|
else
|
|
response->header(h_Vias).front().remove(p_received);
|
|
response->header(h_Vias).front().param(p_rport).port() = mContact.uri().port();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send200ToRegister(const NameAddr& contact)
|
|
{
|
|
return new Send200ToRegister(*this, contact);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send200ToRegister()
|
|
{
|
|
return new Send200ToRegister(*this);
|
|
}
|
|
|
|
TestSipEndPoint::Notify::Notify(TestSipEndPoint & endPoint, std::shared_ptr<resip::Contents> contents,
|
|
const resip::Data& eventPackage, const resip::Data& subscriptionState, int expires, int minExpires, bool firstNotify)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mContents(contents),
|
|
mEventPackage(eventPackage),
|
|
mSubscriptionState(subscriptionState),
|
|
mExpires(expires),
|
|
mMinExpires(minExpires),
|
|
mFirstNotify(firstNotify)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Notify::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
uint32_t expires = msg->header(h_Expires).value();
|
|
if (msg->isRequest() && (expires < mMinExpires))
|
|
{
|
|
std::shared_ptr<resip::SipMessage> response;
|
|
response = mEndPoint.makeResponse(*msg, 423);
|
|
response->header(h_MinExpires).value() = mMinExpires;
|
|
return response;
|
|
}
|
|
else
|
|
{
|
|
resip::Data remoteTag(msg->isRequest() ? msg->header(h_From).param(p_tag) :
|
|
msg->header(h_To).param(p_tag) );
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog(msg->header(h_CallId),remoteTag);
|
|
resip_assert(dialog);
|
|
std::shared_ptr<SipMessage> notify(dialog->makeNotify());
|
|
notify->setContents(mContents.get());
|
|
notify->header(h_Event).value() = mEventPackage;
|
|
notify->header(h_SubscriptionState).value() = mSubscriptionState;
|
|
notify->header(h_SubscriptionState).param(p_expires) = mExpires;
|
|
|
|
if (mFirstNotify)
|
|
{
|
|
notify->header(h_CSeq).sequence() = 0;
|
|
}
|
|
|
|
return notify;
|
|
}
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::notify(std::shared_ptr<resip::Contents> contents, const resip::Data& eventPackage, const resip::Data& subscriptionState, int expires, int minExpires, bool firstNotify)
|
|
{
|
|
return new Notify(*this, contents, eventPackage, subscriptionState, expires, minExpires, firstNotify);
|
|
}
|
|
|
|
TestSipEndPoint::Respond::Respond(TestSipEndPoint& endPoint,
|
|
int responseCode)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mCode(responseCode)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Respond::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
DebugLog(<< "TestSipEndPoint::Respond::go");
|
|
/* !jf! use the dialog */
|
|
if (msg->isRequest() && mCode != 487)
|
|
{
|
|
return mEndPoint.makeResponse(*msg, mCode);
|
|
}
|
|
else
|
|
{
|
|
std::shared_ptr<resip::SipMessage> invite;
|
|
invite = mEndPoint.getReceivedInvite(msg->header(resip::h_CallId));
|
|
if (!invite)
|
|
{
|
|
return mEndPoint.makeResponse(*msg, mCode);
|
|
}
|
|
else
|
|
{
|
|
return mEndPoint.makeResponse(*invite, mCode);
|
|
}
|
|
}
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::respond(int code)
|
|
{
|
|
return new Respond(*this, code);
|
|
}
|
|
|
|
TestSipEndPoint::Answer::Answer(TestSipEndPoint & endPoint, const std::shared_ptr<resip::SdpContents> sdp)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mSdp(sdp)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Answer::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> invite;
|
|
invite = mEndPoint.getReceivedInvite(msg->header(resip::h_CallId));
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*invite, 200);
|
|
|
|
const resip::SdpContents* sdp=0;
|
|
if( mSdp.get() )
|
|
{
|
|
sdp = dynamic_cast<const resip::SdpContents*>(mSdp.get());
|
|
response->setContents(sdp);
|
|
}
|
|
else
|
|
{
|
|
//sdp = dynamic_cast<const resip::SdpContents*>(invite->getContents());
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::answer()
|
|
{
|
|
return new Answer(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::answer(std::shared_ptr<resip::SdpContents> sdp)
|
|
{
|
|
return new Answer(*this, sdp);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::AnswerUpdate::AnswerUpdate(TestSipEndPoint & endPoint, std::shared_ptr<resip::SdpContents> sdp)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mSdp(sdp)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::AnswerUpdate::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> update;
|
|
update = mEndPoint.getReceivedUpdate(msg->header(resip::h_CallId));
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*update, 200);
|
|
|
|
const resip::SdpContents* sdp=0;
|
|
if( mSdp.get() )
|
|
{
|
|
sdp = dynamic_cast<const resip::SdpContents*>(mSdp.get());
|
|
response->setContents(sdp);
|
|
}
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::answerUpdate()
|
|
{
|
|
return new AnswerUpdate(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::answerUpdate(std::shared_ptr<resip::SdpContents> sdp)
|
|
{
|
|
return new AnswerUpdate(*this, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::AnswerTo::AnswerTo(
|
|
TestSipEndPoint& endPoint,
|
|
const std::shared_ptr<resip::SipMessage>& msg,
|
|
std::shared_ptr<resip::SdpContents> sdp
|
|
) :
|
|
MessageAction(endPoint, Uri()),
|
|
mMsg(msg),
|
|
mSdp(sdp)
|
|
{}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::AnswerTo::go()
|
|
{
|
|
std::shared_ptr<resip::SipMessage> invite;
|
|
invite = mEndPoint.getReceivedInvite(mMsg->header(resip::h_CallId));
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*invite, 200);
|
|
const resip::SdpContents* sdp;
|
|
if (mSdp)
|
|
sdp = dynamic_cast<const resip::SdpContents*>(mSdp.get());
|
|
else
|
|
sdp = dynamic_cast<const resip::SdpContents*>(invite->getContents());
|
|
response->setContents(sdp);
|
|
return response;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::AnswerTo::toString() const
|
|
{
|
|
return mEndPoint.getName() + ".answer()";
|
|
}
|
|
|
|
|
|
TestSipEndPoint::MessageAction*
|
|
TestSipEndPoint::answerTo(
|
|
const std::shared_ptr<resip::SipMessage>& invite,
|
|
std::shared_ptr<resip::SdpContents> sdp
|
|
)
|
|
{
|
|
return new AnswerTo(*this, invite, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ring()
|
|
{
|
|
return new Ring(*this);
|
|
}
|
|
|
|
TestSipEndPoint::RingNewBranch::RingNewBranch(TestSipEndPoint& endPoint)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::RingNewBranch::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> inv = mEndPoint.getReceivedInvite(msg->header(resip::h_CallId));
|
|
//std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*inv, 183);
|
|
|
|
SipMessage& request = *inv;
|
|
|
|
resip_assert(request.isRequest());
|
|
int responseCode = 180;
|
|
if (request.header(h_RequestLine).getMethod() == INVITE)
|
|
{
|
|
//DeprecatedDialog* dialog = getDialog(request.header(h_CallId));
|
|
//if (!dialog)
|
|
//{
|
|
DebugLog(<< "making a dialog, contact: " << mEndPoint.getContact());
|
|
DeprecatedDialog* dialog = new DeprecatedDialog(mEndPoint.getContact());
|
|
mEndPoint.mDialogs.push_back(dialog);
|
|
DebugLog(<< "made a dialog (" << dialog << "), contact: " << mEndPoint.getContact());
|
|
//}
|
|
DebugLog(<< "Creating response using dialog: " << dialog);
|
|
std::shared_ptr<SipMessage> response(dialog->makeResponse(request, responseCode));
|
|
|
|
return response;
|
|
}
|
|
else
|
|
{
|
|
DebugLog(<<"RingNewBranch error -- original request must be an INVITE!!!");
|
|
throw AssertException("RingNewBranch error -- original request must be an INVITE!!!",
|
|
__FILE__, __LINE__);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ringNewBranch()
|
|
{
|
|
return new RingNewBranch(*this);
|
|
}
|
|
|
|
TestSipEndPoint::Ring183::Ring183(TestSipEndPoint & endPoint, std::shared_ptr<resip::SdpContents> sdp, bool removeContact)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mSdp(sdp),
|
|
mReliable(false),
|
|
mRseq(0),
|
|
mRemoveContact(removeContact)
|
|
{
|
|
}
|
|
|
|
TestSipEndPoint::Ring183::Ring183(TestSipEndPoint & endPoint, std::shared_ptr<resip::SdpContents> sdp, int rseq)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mSdp(sdp),
|
|
mReliable(true),
|
|
mRseq(rseq),
|
|
mRemoveContact(false)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Ring183::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> inv = mEndPoint.getReceivedInvite(msg->header(resip::h_CallId));
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*inv, 183);
|
|
|
|
if (mReliable)
|
|
{
|
|
bool required = inv->exists(h_Requires) && inv->header(h_Requires).find(Token(Symbols::C100rel));
|
|
bool supported = inv->exists(h_Supporteds) && inv->header(h_Supporteds).find(Token(Symbols::C100rel));
|
|
|
|
if ( mReliable && (!required && !supported) )
|
|
{
|
|
InfoLog (<< "Supported header: " << Inserter(inv->header(h_Supporteds))
|
|
<< " : "
|
|
<< inv->header(h_Supporteds).find(Token(Symbols::C100rel)));
|
|
|
|
throw AssertException("Trying to send reliable provisional when UAC doesn't support it",
|
|
__FILE__, __LINE__);
|
|
}
|
|
if (!mReliable && required)
|
|
{
|
|
throw AssertException("Failing to send reliable provisional when UAC requires it",
|
|
__FILE__, __LINE__);
|
|
}
|
|
|
|
// if (mReliable && msg->header(h_RequestLine).method() != INVITE)
|
|
// {
|
|
// throw AssertException("Requesting reliable provisional on non-INVITE method",
|
|
// __FILE__, __LINE__);
|
|
// }
|
|
|
|
if (mReliable)
|
|
{
|
|
response->header(h_Requires).push_back(Token(Symbols::C100rel));
|
|
response->header(h_RSeq).value() = mRseq;
|
|
}
|
|
}
|
|
|
|
if (mSdp)
|
|
{
|
|
response->setContents(mSdp.get());
|
|
}
|
|
|
|
if (mRemoveContact)
|
|
{
|
|
response->remove(h_Contacts);
|
|
}
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ring183()
|
|
{
|
|
return new Ring183(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ring183(std::shared_ptr<resip::SdpContents> sdp)
|
|
{
|
|
return new Ring183(*this, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ring183_missingContact(std::shared_ptr<resip::SdpContents> sdp)
|
|
{
|
|
return new Ring183(*this, sdp, true);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::reliableProvisional(std::shared_ptr<resip::SdpContents> sdp, int rseq)
|
|
{
|
|
if (rseq <= 0)
|
|
{
|
|
throw AssertException("RSEQ value must be greater than 0",
|
|
__FILE__, __LINE__);
|
|
}
|
|
return new Ring183(*this, sdp, rseq);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::reliableProvisional(int rseq)
|
|
{
|
|
if (rseq <= 0)
|
|
{
|
|
throw AssertException("RSEQ value must be greater than 0",
|
|
__FILE__, __LINE__);
|
|
}
|
|
return new Ring183(*this, nullptr, rseq);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ok()
|
|
{
|
|
return new Ok(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send401()
|
|
{
|
|
return new Send401(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send403()
|
|
{
|
|
return new Send403(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send404()
|
|
{
|
|
return new Send404(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send415()
|
|
{
|
|
return new Send415(*this);
|
|
}
|
|
|
|
TestSipEndPoint::Send420::Send420(TestSipEndPoint & endPoint, const Token& unsupported)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mUnsupported(unsupported)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Send420::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<resip::SipMessage> response = mEndPoint.makeResponse(*msg, 420);
|
|
response->header(h_Unsupporteds).push_back(mUnsupported);
|
|
return response;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send420(const resip::Token& unsupported)
|
|
{
|
|
return new Send420(*this, unsupported);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send480()
|
|
{
|
|
return new Send480(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send486()
|
|
{
|
|
return new Send486(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send487()
|
|
{
|
|
return new Send487(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send488()
|
|
{
|
|
return new Send488(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send491()
|
|
{
|
|
return new Send491(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send202()
|
|
{
|
|
return new Send202(*this);
|
|
}
|
|
|
|
// vk
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send200()
|
|
{
|
|
return new Send200(*this);
|
|
}
|
|
// end - vk
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send100()
|
|
{
|
|
return new Send100(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send503()
|
|
{
|
|
return new Send503(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send500()
|
|
{
|
|
return new Send500(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send513()
|
|
{
|
|
return new Send513(*this);
|
|
}
|
|
|
|
// vk
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send501()
|
|
{
|
|
return new Send501(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send502()
|
|
{
|
|
return new Send502(*this);
|
|
}
|
|
// end- vk
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send504()
|
|
{
|
|
return new Send504(*this);
|
|
}
|
|
|
|
// vk
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send506()
|
|
{
|
|
return new Send506(*this);
|
|
}
|
|
// end- vk
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send600()
|
|
{
|
|
return new Send600(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send603()
|
|
{
|
|
return new Send603(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send604()
|
|
{
|
|
return new Send604(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::send606()
|
|
{
|
|
return new Send606(*this);
|
|
}
|
|
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::dump()
|
|
{
|
|
return new Dump(*this);
|
|
}
|
|
|
|
TestSipEndPoint::Ack::Ack(TestSipEndPoint & endPoint, std::shared_ptr<resip::SdpContents> sdp)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mSdp(sdp)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Ack::go(std::shared_ptr<SipMessage> response)
|
|
{
|
|
resip_assert(response->isResponse());
|
|
int code = response->header(h_StatusLine).responseCode();
|
|
std::shared_ptr<SipMessage> invite;
|
|
try
|
|
{
|
|
invite = mEndPoint.getSentInvite(response->header(h_CallId));
|
|
}
|
|
catch(...)
|
|
{
|
|
if(!mEndPoint.mRequests.empty())
|
|
{
|
|
invite = mEndPoint.mRequests.begin()->second;
|
|
}
|
|
}
|
|
|
|
|
|
if (code == 200)
|
|
{
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog(response->header(h_CallId),
|
|
response->header(h_To).param(p_tag));
|
|
if(dialog)
|
|
{
|
|
DebugLog(<< "Constructing ack against 200 using dialog.");
|
|
DebugLog(<< *dialog);
|
|
// !dlb! should use contact from 200?
|
|
std::shared_ptr<SipMessage> ack(dialog->makeAck(*invite));
|
|
if (mSdp)
|
|
ack->setContents(mSdp.get());
|
|
return ack;
|
|
}
|
|
else
|
|
{
|
|
DebugLog(<< "Constructing ack against 200 using Helper.");
|
|
// Allow garbage ACK (ACK to non-INVITE)
|
|
MethodTypes method=invite->method();
|
|
invite->header(h_RequestLine).method()=INVITE;
|
|
invite->header(h_CSeq).method()=INVITE;
|
|
std::shared_ptr<SipMessage> ack(Helper::makeFailureAck(*invite,*response));
|
|
// Reset tid
|
|
ack->header(h_Vias).front().param(p_branch).reset();
|
|
// Reset request-line
|
|
ack->header(h_RequestLine).uri()=response->header(h_Contacts).front().uri();
|
|
// Set Routes
|
|
if(!response->empty(h_RecordRoutes))
|
|
{
|
|
ack->header(h_Routes)=response->header(h_RecordRoutes).reverse();
|
|
}
|
|
if (mSdp)
|
|
ack->setContents(mSdp.get());
|
|
invite->header(h_RequestLine).method()=method;
|
|
invite->header(h_CSeq).method()=method;
|
|
return ack;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugLog(<<"Constructing failure ack.");
|
|
// Allow garbage ACK (ACK to non-INVITE)
|
|
MethodTypes method=invite->method();
|
|
invite->header(h_RequestLine).method()=INVITE;
|
|
invite->header(h_CSeq).method()=INVITE;
|
|
std::shared_ptr<SipMessage> ack(Helper::makeFailureAck(*invite, *response));
|
|
invite->header(h_RequestLine).method()=method;
|
|
invite->header(h_CSeq).method()=method;
|
|
ack->header(h_Vias).front().param(p_branch).reset(response->getTransactionId());
|
|
return ack;
|
|
}
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ack()
|
|
{
|
|
return new Ack(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ack(std::shared_ptr<resip::SdpContents> sdp)
|
|
{
|
|
return new Ack(*this, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::AckNewTid::AckNewTid(TestSipEndPoint & endPoint, std::shared_ptr<resip::SdpContents> sdp)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mSdp(sdp)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::AckNewTid::go(std::shared_ptr<SipMessage> response)
|
|
{
|
|
resip_assert(response->isResponse());
|
|
int code = response->header(h_StatusLine).responseCode();
|
|
std::shared_ptr<SipMessage> invite = mEndPoint.getSentInvite(response->header(h_CallId));
|
|
resip_assert (invite->header(h_RequestLine).getMethod() == INVITE);
|
|
|
|
std::shared_ptr<SipMessage> ack;
|
|
|
|
if (code == 200)
|
|
{
|
|
DebugLog(<< "Constructing ack against 200 using dialog.");
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog(response->header(h_CallId),
|
|
response->header(h_To).param(p_tag));
|
|
resip_assert (dialog);
|
|
DebugLog(<< *dialog);
|
|
// !dlb! should use contact from 200?
|
|
ack.reset(dialog->makeAck(*invite));
|
|
if (mSdp)
|
|
ack->setContents(mSdp.get());
|
|
}
|
|
else
|
|
{
|
|
DebugLog(<<"Constructing failure ack.");
|
|
ack.reset(Helper::makeFailureAck(*invite, *response));
|
|
}
|
|
|
|
ack->header(h_Vias).front().param(p_branch).reset();
|
|
|
|
return ack;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ackNewTid()
|
|
{
|
|
return new AckNewTid(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ackNewTid(std::shared_ptr<resip::SdpContents> sdp)
|
|
{
|
|
return new AckNewTid(*this, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::AckOldTid::AckOldTid(TestSipEndPoint & endPoint, std::shared_ptr<resip::SdpContents> sdp)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mSdp(sdp)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::AckOldTid::go(std::shared_ptr<SipMessage> response)
|
|
{
|
|
resip_assert(response->isResponse());
|
|
int code = response->header(h_StatusLine).responseCode();
|
|
std::shared_ptr<SipMessage> invite = mEndPoint.getSentInvite(response->header(h_CallId));
|
|
resip_assert (invite->header(h_RequestLine).getMethod() == INVITE);
|
|
|
|
std::shared_ptr<SipMessage> ack;
|
|
|
|
if (code == 200)
|
|
{
|
|
DebugLog(<< "Constructing ack against 200 using dialog.");
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog(response->header(h_CallId),
|
|
response->header(h_To).param(p_tag));
|
|
resip_assert (dialog);
|
|
DebugLog(<< *dialog);
|
|
// !dlb! should use contact from 200?
|
|
ack.reset(dialog->makeAck(*invite));
|
|
if (mSdp)
|
|
ack->setContents(mSdp.get());
|
|
}
|
|
else
|
|
{
|
|
DebugLog(<<"Constructing failure ack.");
|
|
ack.reset(Helper::makeFailureAck(*invite, *response));
|
|
}
|
|
|
|
resip::Data oldTid(invite->header(h_Vias).front().param(p_branch).getTransactionId());
|
|
|
|
ack->header(h_Vias).front().param(p_branch).reset(oldTid);
|
|
return ack;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ackOldTid()
|
|
{
|
|
return new AckOldTid(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ackOldTid(std::shared_ptr<resip::SdpContents> sdp)
|
|
{
|
|
return new AckOldTid(*this, sdp);
|
|
}
|
|
|
|
TestSipEndPoint::Reflect::Reflect(TestSipEndPoint& endPoint, MethodTypes method, const Uri& to):
|
|
MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mMethod(method),
|
|
mReqUri(to)
|
|
{}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
TestSipEndPoint::Reflect::go(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
std::shared_ptr<SipMessage> reflect(static_cast<SipMessage*>(msg->clone()));
|
|
if(mMethod!=UNKNOWN)
|
|
{
|
|
if(reflect->isRequest())
|
|
{
|
|
reflect->header(h_RequestLine).method()=mMethod;
|
|
}
|
|
|
|
reflect->header(h_CSeq).method()=mMethod;
|
|
}
|
|
|
|
if(reflect->isRequest())
|
|
{
|
|
reflect->header(h_RequestLine).uri()=mReqUri;
|
|
}
|
|
|
|
if(mMethod == INVITE)
|
|
{
|
|
mEndPoint.storeSentInvite(reflect);
|
|
}
|
|
return reflect;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::reflect(const Uri& reqUri,MethodTypes method)
|
|
{
|
|
return new Reflect(*this,method,reqUri);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::reflect(const TestUser& user,MethodTypes method)
|
|
{
|
|
return new Reflect(*this,method,user.getAddressOfRecord());
|
|
}
|
|
|
|
#if 0
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::ackReferred()
|
|
{
|
|
return new AckReferred(*this);
|
|
}
|
|
#endif
|
|
|
|
ExpectAction*
|
|
TestSipEndPoint::bye(const resip::Uri& target)
|
|
{
|
|
return new ByeTo(*this, target);
|
|
}
|
|
|
|
ExpectAction*
|
|
TestSipEndPoint::bye(const TestSipEndPoint* target)
|
|
{
|
|
return new ByeTo(*this, target->getContact().uri());
|
|
}
|
|
|
|
ExpectAction*
|
|
TestSipEndPoint::bye(const TestSipEndPoint& target)
|
|
{
|
|
return new ByeTo(*this, target.getContact().uri());
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::bye()
|
|
{
|
|
return new Bye(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::cancel()
|
|
{
|
|
return new Cancel(*this);
|
|
}
|
|
|
|
TestSipEndPoint::Prack::Prack(TestSipEndPoint & endPoint, std::shared_ptr<resip::SdpContents> sdp)
|
|
: MessageExpectAction(endPoint),
|
|
mEndPoint(endPoint),
|
|
mSdp(sdp)
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Prack::go(std::shared_ptr<SipMessage> msg)
|
|
{
|
|
resip::Data remoteTag(msg->isRequest() ? msg->header(h_From).param(p_tag) :
|
|
msg->header(h_To).param(p_tag) );
|
|
DeprecatedDialog* dialog = mEndPoint.getDialog(msg->header(h_CallId),remoteTag);
|
|
if(!dialog)
|
|
{
|
|
resip::Data localTag(!msg->isRequest() ? msg->header(h_From).param(p_tag):
|
|
msg->header(h_To).param(p_tag) );
|
|
dialog=mEndPoint.getDialog(msg->header(h_CallId),localTag);
|
|
}
|
|
resip_assert(dialog);
|
|
std::shared_ptr<SipMessage> prack(dialog->makeRequest(PRACK));
|
|
|
|
// Add RAck header
|
|
prack->header(h_RAck) = mEndPoint.mRelRespInfo;
|
|
|
|
// Add body if provided
|
|
if(mSdp.get())
|
|
{
|
|
prack->setContents(mSdp.get());
|
|
}
|
|
|
|
return prack;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::prack()
|
|
{
|
|
return new Prack(*this);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::prack(std::shared_ptr<resip::SdpContents> sdp)
|
|
{
|
|
return new Prack(*this, sdp);
|
|
}
|
|
|
|
ExpectAction*
|
|
TestSipEndPoint::notify200(const resip::Uri& target)
|
|
{
|
|
return new Notify200To(*this, target);
|
|
}
|
|
|
|
ExpectAction*
|
|
TestSipEndPoint::notify200(const TestSipEndPoint& target)
|
|
{
|
|
return new Notify200To(*this, target.getContact().uri());
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
TestSipEndPoint::notify200()
|
|
{
|
|
return new Notify200(*this);
|
|
}
|
|
|
|
TestSipEndPoint::SaveMatcher::SaveMatcher(Matcher* matcher, std::shared_ptr<SipMessage>& msg) :
|
|
mMsg(msg),
|
|
mMatcher(matcher)
|
|
{
|
|
}
|
|
|
|
Data
|
|
TestSipEndPoint::SaveMatcher::toString() const
|
|
{
|
|
return "SaveMatcher: " + mMatcher->toString();
|
|
}
|
|
|
|
bool
|
|
TestSipEndPoint::SaveMatcher::isMatch(std::shared_ptr<resip::SipMessage>& message) const
|
|
{
|
|
TestSipEndPoint::SaveMatcher* ncThis = const_cast<TestSipEndPoint::SaveMatcher*>(this);
|
|
ncThis->mMsg = message;
|
|
return mMatcher->isMatch(message);
|
|
}
|
|
|
|
TestSipEndPoint::From::From(const TestSipEndPoint& testEndPoint)
|
|
: mEndPoint(&testEndPoint),
|
|
mProxy(0),
|
|
mContact()
|
|
{
|
|
resip_assert(mEndPoint);
|
|
}
|
|
|
|
TestSipEndPoint::From::From(TestProxy& testProxy)
|
|
: mEndPoint(0),
|
|
mProxy(&testProxy),
|
|
mContact()
|
|
{
|
|
resip_assert(mProxy);
|
|
}
|
|
|
|
TestSipEndPoint::From::From(const resip::Uri& contact)
|
|
: mEndPoint(0),
|
|
mProxy(0),
|
|
mContact(contact)
|
|
{
|
|
resip_assert(!mContact.host().empty());
|
|
}
|
|
|
|
TestSipEndPoint::From::From(const resip::Data& instanceId)
|
|
: mEndPoint(0),
|
|
mProxy(0),
|
|
mContact(),
|
|
mInstanceId(instanceId)
|
|
{
|
|
resip_assert(!instanceId.empty());
|
|
}
|
|
|
|
|
|
// check if the message is within a known transaction
|
|
// check via
|
|
// check max-forwards
|
|
// check record-route
|
|
// check route
|
|
// this requires the endpoint to store all sent and received requests, not just
|
|
// INVITE and SUBSCRIBE?
|
|
bool
|
|
TestSipEndPoint::From::isMatch(std::shared_ptr<SipMessage>& message) const
|
|
{
|
|
//DebugLog(<< "TestSipEndPoint::From::isMatch");
|
|
// check that the from matches the stored agent
|
|
if (!mInstanceId.empty())
|
|
{
|
|
if (message->exists(h_Contacts) && message->header(h_Contacts).size() == 1)
|
|
{
|
|
if (message->header(h_Contacts).front().exists(p_Instance))
|
|
{
|
|
if (message->header(h_Contacts).front().param(p_Instance) == mInstanceId)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
DebugLog (<< "instanceId doesn't match "
|
|
<< message->header(h_Contacts).front().param(p_Instance) << " != "
|
|
<< mInstanceId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugLog (<< "no instanceId in contact " << message->header(h_Contacts).front());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugLog (<< "wrong number of contacts in msg ");
|
|
}
|
|
return false;
|
|
}
|
|
else if (mEndPoint || !mContact.host().empty())
|
|
{
|
|
const Uri& localContact = mEndPoint ? mEndPoint->getContact().uri() : mContact;
|
|
if (message->isRequest())
|
|
{
|
|
if (message->exists(h_Contacts) && message->header(h_Contacts).size() == 1)
|
|
{
|
|
if (localContact.getAor() == message->header(h_Contacts).front().uri().getAor())
|
|
{
|
|
DebugLog(<< "matched");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
Via& via = message->header(h_Vias).back(); // via of originator
|
|
DebugLog(<< "Trying to match: " << via.sentHost() << ":" << via.sentPort() << " against: " << localContact);
|
|
|
|
if ((via.sentHost() != localContact.host()
|
|
&& !(via.exists(p_received) && via.param(p_received) == localContact.host()))
|
|
|| via.sentPort() != localContact.port())
|
|
{
|
|
InfoLog(<< "From::isMatch failed for (endPoint) "
|
|
<< (mEndPoint ? mEndPoint->getName() : "")
|
|
<< ". Via did not match in command");
|
|
return false;
|
|
}
|
|
//DebugLog("matched");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
|
|
NameAddrs& contacts = message->header(h_Contacts);
|
|
if (contacts.size() == 0)
|
|
{
|
|
InfoLog(<< "From::isMatch failed for (endPoint) " << mEndPoint->getName());
|
|
InfoLog(<< "No contact header was present in the message: " );
|
|
return false;
|
|
}
|
|
if (contacts.size() != 1)
|
|
{
|
|
InfoLog(<< "From::isMatch failed for (endPoint) " << mEndPoint->getName());
|
|
InfoLog(<< "More than one contact header was present in the message: " );
|
|
return false;
|
|
}
|
|
if ( !(localContact.getAor() == contacts.front().uri().getAor()))
|
|
{
|
|
InfoLog(<< "From::isMatch failed for (endPoint) " << mEndPoint->getName());
|
|
InfoLog(<< "Expected: " << localContact << ", got: " << contacts.front().uri().getAor() << " in msg: " );
|
|
return false;
|
|
}
|
|
//DebugLog("matched");
|
|
return true;
|
|
}
|
|
else if (mProxy)
|
|
{
|
|
DebugLog(<< "using proxy->isFromMe");
|
|
return mProxy->isFromMe(*message);
|
|
}
|
|
resip_assert(false);
|
|
return false;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::From::toString() const
|
|
{
|
|
if (mEndPoint)
|
|
{
|
|
return "from(" + mEndPoint->getName() + ")";
|
|
}
|
|
else if (!mContact.host().empty())
|
|
{
|
|
return "from(" + mContact.getAor() + ")";
|
|
}
|
|
else if (mProxy)
|
|
{
|
|
return "from(" + mProxy->toString() + ")";
|
|
}
|
|
else if (!mInstanceId.empty())
|
|
{
|
|
return "from(" + mInstanceId + ")";
|
|
}
|
|
|
|
resip_assert(false);
|
|
return Data::Empty;
|
|
}
|
|
|
|
TestSipEndPoint::Contact::Contact(const TestSipEndPoint& testEndPoint)
|
|
: mEndPoint(&testEndPoint),
|
|
mProxy(0),
|
|
mContact()
|
|
{
|
|
resip_assert(mEndPoint);
|
|
}
|
|
|
|
TestSipEndPoint::Contact::Contact(TestProxy& testProxy)
|
|
: mEndPoint(0),
|
|
mProxy(&testProxy),
|
|
mContact()
|
|
{
|
|
}
|
|
|
|
TestSipEndPoint::Contact::Contact(const resip::Uri& contact)
|
|
: mEndPoint(0),
|
|
mProxy(0),
|
|
mContact(contact)
|
|
{
|
|
}
|
|
|
|
bool
|
|
TestSipEndPoint::Contact::isMatch(std::shared_ptr<SipMessage>& message) const
|
|
{
|
|
if (message->exists(h_Contacts) &&
|
|
message->header(h_Contacts).size() == 1)
|
|
{
|
|
bool ret;
|
|
if (mEndPoint)
|
|
{
|
|
DebugLog(<< "Contact::isMatch " << message->header(h_Contacts).front().uri().getAor()
|
|
<< " " << mEndPoint->getContact().uri().getAor());
|
|
ret = message->header(h_Contacts).front().uri().getAor() == mEndPoint->getContact().uri().getAor();
|
|
}
|
|
else if (!mContact.host().empty())
|
|
{
|
|
DebugLog(<< "Contact::isMatch " << message->header(h_Contacts).front().uri().getAor()
|
|
<< " " << mContact.getAor());
|
|
ret = message->header(h_Contacts).front().uri().getAor() == mContact.getAor();
|
|
}
|
|
else
|
|
{
|
|
DebugLog(<< "Contact::isMatch " << message->header(h_Contacts).front().uri().getAor()
|
|
<< " " << mProxy->getContact().uri().getAor());
|
|
ret = message->header(h_Contacts).front().uri().getAor() == mProxy->getContact().uri().getAor();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
InfoLog(<< "Contact::isMatch: no contacts");
|
|
return false;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::Contact::toString() const
|
|
{
|
|
if (mEndPoint)
|
|
{
|
|
return "contact(" + mEndPoint->getName() + ")";
|
|
}
|
|
else if (!mContact.host().empty())
|
|
{
|
|
return "contact(" + mContact.getAor() + ")";
|
|
}
|
|
else
|
|
{
|
|
return "contact(" + mProxy->toString() + ")";
|
|
}
|
|
}
|
|
|
|
TestSipEndPoint::Contact*
|
|
contact(const TestSipEndPoint& testEndPoint)
|
|
{
|
|
return new TestSipEndPoint::Contact(testEndPoint);
|
|
}
|
|
|
|
TestSipEndPoint::Contact*
|
|
contact(TestProxy& testProxy)
|
|
{
|
|
return new TestSipEndPoint::Contact(testProxy);
|
|
}
|
|
|
|
TestSipEndPoint::Contact*
|
|
contact(const TestSipEndPoint* testEndPoint)
|
|
{
|
|
resip_assert (testEndPoint);
|
|
return new TestSipEndPoint::Contact(*testEndPoint);
|
|
}
|
|
|
|
TestSipEndPoint::Contact*
|
|
contact(TestProxy* testProxy)
|
|
{
|
|
return new TestSipEndPoint::Contact(*testProxy);
|
|
}
|
|
|
|
TestSipEndPoint::Contact*
|
|
contact(const Uri& contact)
|
|
{
|
|
return new TestSipEndPoint::Contact(contact);
|
|
}
|
|
|
|
TestSipEndPoint::Contact*
|
|
contact(const NameAddr& contact)
|
|
{
|
|
return new TestSipEndPoint::Contact(contact.uri());
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::HasMessageBodyMatch::toString() const
|
|
{
|
|
return "HasMessageBodyMatch";
|
|
}
|
|
|
|
bool
|
|
TestSipEndPoint::HasMessageBodyMatch::isMatch(std::shared_ptr<SipMessage>& message) const
|
|
{
|
|
if (message->exists(h_ContentLength) && message->header(h_ContentLength).value())
|
|
{
|
|
return true;
|
|
}
|
|
DebugLog(<< "HasMessageBodyMatch::isMatch failed: no body in the message");
|
|
return false;
|
|
}
|
|
|
|
TestSipEndPoint::HasMessageBodyMatch* hasMessageBodyMatch()
|
|
{
|
|
return new TestSipEndPoint::HasMessageBodyMatch();
|
|
}
|
|
|
|
// JF
|
|
|
|
TestSipEndPoint::UnknownHeaderMatch::UnknownHeaderMatch(const resip::Data& name, const resip::Data& value)
|
|
: mName(name), mValue(value)
|
|
{
|
|
}
|
|
|
|
TestSipEndPoint::UnknownHeaderMatch*
|
|
unknownHeaderMatch(const resip::Data& name, const resip::Data& value)
|
|
{
|
|
return new TestSipEndPoint::UnknownHeaderMatch(name,value);
|
|
}
|
|
|
|
|
|
resip::Data
|
|
TestSipEndPoint::UnknownHeaderMatch::toString() const
|
|
{
|
|
return "UnknownHeaderMatch("+mName+","+mValue+")";
|
|
}
|
|
|
|
|
|
bool
|
|
TestSipEndPoint::UnknownHeaderMatch::isMatch(std::shared_ptr<SipMessage>& message) const
|
|
{
|
|
return ( message->exists(resip::UnknownHeaderType(mName))
|
|
&& message->header(resip::UnknownHeaderType(mName)).front().value() == mValue
|
|
);
|
|
}
|
|
|
|
|
|
std::shared_ptr<SipMessage>
|
|
TestSipEndPoint::Cancel::go(std::shared_ptr<SipMessage> msg)
|
|
{
|
|
std::shared_ptr<SipMessage> invite;
|
|
try
|
|
{
|
|
invite = mEndPoint.getSentInvite(msg->header(h_CallId));
|
|
}
|
|
catch(...)
|
|
{
|
|
if(!mEndPoint.mRequests.empty())
|
|
{
|
|
invite= mEndPoint.mRequests.begin()->second;
|
|
}
|
|
}
|
|
|
|
resip_assert(invite!=0);
|
|
// Allow for CANCEL to be sent for non-INVITE.
|
|
MethodTypes method=invite->method();
|
|
invite->header(h_RequestLine).method()=INVITE;
|
|
invite->header(h_CSeq).method()=INVITE;
|
|
std::shared_ptr<SipMessage> cancel(Helper::makeCancel(*invite));
|
|
invite->header(h_RequestLine).method()=method;
|
|
invite->header(h_CSeq).method()=method;
|
|
return cancel;
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::NoAction::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
TestSipEndPoint::ToMatch::ToMatch(const TestSipEndPoint& ep,
|
|
const resip::Uri& to)
|
|
: mEndPoint(&ep),
|
|
mTo(to)
|
|
{}
|
|
|
|
Data
|
|
TestSipEndPoint::ToMatch::toString() const
|
|
{
|
|
return mEndPoint->getName() + ".toMatch(" + Data::from(mTo) + ")";
|
|
}
|
|
|
|
bool
|
|
TestSipEndPoint::ToMatch::passes(std::shared_ptr<Event> event)
|
|
{
|
|
SipEvent* sipEvent = dynamic_cast<SipEvent*>(event.get());
|
|
resip_assert(sipEvent);
|
|
resip_assert(mEndPoint);
|
|
|
|
DebugLog(<< "TestSipEndPoint::ToMatch(" << Data::from(mTo) << " ? " << Data::from(sipEvent->getMessage()->header(h_To)) << ")");
|
|
return (sipEvent->getMessage()->exists(h_To) &&
|
|
sipEvent->getMessage()->header(h_To).uri() == mTo);
|
|
}
|
|
|
|
|
|
|
|
TestSipEndPoint::ToMatch&
|
|
TestSipEndPoint::toMatch(const resip::Uri& to)
|
|
{
|
|
TestSipEndPoint::ToMatch* toMatch = new TestSipEndPoint::ToMatch(*this, to);
|
|
// !dlb! leak...
|
|
return *toMatch;
|
|
}
|
|
|
|
//---
|
|
|
|
TestSipEndPoint::SipExpect::SipExpect(TestSipEndPoint& endPoint,
|
|
std::pair<resip::MethodTypes, int> msgTypeCode,
|
|
Matcher* matcher,
|
|
ExpectPreCon& preCon,
|
|
int timeoutMs,
|
|
ActionBase* expectAction)
|
|
: mEndPoint(endPoint),
|
|
mMsgTypeCode(msgTypeCode),
|
|
mMatcher(matcher),
|
|
mPreCon(preCon),
|
|
mTimeoutMs(timeoutMs*TestEndPoint::DebugTimeMult()),
|
|
mExpectAction(expectAction)
|
|
{
|
|
}
|
|
|
|
TestSipEndPoint::SipExpect::~SipExpect()
|
|
{
|
|
delete mExpectAction;
|
|
delete mMatcher;
|
|
}
|
|
|
|
TestEndPoint*
|
|
TestSipEndPoint::SipExpect::getEndPoint() const
|
|
{
|
|
return &mEndPoint;
|
|
}
|
|
|
|
unsigned int
|
|
TestSipEndPoint::SipExpect::getTimeout() const
|
|
{
|
|
return mTimeoutMs;
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::SipExpect::onEvent(TestEndPoint& endPoint, std::shared_ptr<Event> event)
|
|
{
|
|
mExpectAction->exec(event);
|
|
}
|
|
resip::Data
|
|
TestSipEndPoint::SipExpect::getMsgTypeString() const
|
|
{
|
|
if (mMsgTypeCode.second != 0)
|
|
{
|
|
return getMethodName(mMsgTypeCode.first) + "/" + resip::Data(mMsgTypeCode.second);
|
|
}
|
|
else
|
|
{
|
|
return getMethodName(mMsgTypeCode.first);
|
|
}
|
|
}
|
|
|
|
EncodeStream&
|
|
TestSipEndPoint::SipExpect::output(EncodeStream& s) const
|
|
{
|
|
if (isOptional())
|
|
{
|
|
s << "opt(";
|
|
}
|
|
|
|
s << mEndPoint.getName() << ".expect(" << getMsgTypeString() << ", " << mMatcher->toString() << ")";
|
|
|
|
if (isOptional())
|
|
{
|
|
s << ")";
|
|
}
|
|
|
|
s.flush();
|
|
return s;
|
|
}
|
|
|
|
bool
|
|
TestSipEndPoint::SipExpect::isMatch(std::shared_ptr<Event> event) const
|
|
{
|
|
DebugLog (<< "matching: " << *event);
|
|
SipEvent* sipEvent = dynamic_cast<SipEvent*>(event.get());
|
|
if (!sipEvent) return false;
|
|
|
|
std::shared_ptr<SipMessage> msg = sipEvent->getMessage();
|
|
|
|
TestSipEndPoint* endPoint = dynamic_cast<TestSipEndPoint*>(sipEvent->getEndPoint());
|
|
resip_assert(endPoint);
|
|
|
|
// check to
|
|
//DebugLog(<< "Matching stored endpoint: " << mEndPoint << ":" << mEndPoint.getPort() << " against: " << *endPoint << ":" << endPoint->getPort());
|
|
if (&mEndPoint != endPoint)
|
|
{
|
|
DebugLog(<< "Matching stored endpoint: " << mEndPoint << ":" << mEndPoint.getPort() << " against: " << *endPoint << ":" << endPoint->getPort());
|
|
DebugLog(<< "isMatch failed on endPoint");
|
|
return false;
|
|
}
|
|
|
|
// check from
|
|
if (!mMatcher->isMatch(msg))
|
|
{
|
|
DebugLog(<< "isMatch failed on matcher");
|
|
return false;
|
|
}
|
|
|
|
if(!mPreCon.passes(event))
|
|
{
|
|
DebugLog(<< "isMatch failed on precondition: " << mPreCon.toString());
|
|
return false;
|
|
}
|
|
|
|
if (msg->isResponse())
|
|
{
|
|
if (msg->header(h_CSeq).method() != mMsgTypeCode.first)
|
|
{
|
|
DebugLog(<< "isMatch failed on method.");
|
|
return false;
|
|
}
|
|
|
|
if (msg->header(h_StatusLine).responseCode() != mMsgTypeCode.second)
|
|
{
|
|
DebugLog(<< "isMatch failed on response code: "
|
|
<< msg->header(h_StatusLine).responseCode()
|
|
<< ", needed: " << mMsgTypeCode.second);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
DebugLog(<< "message header: " << msg->header(h_RequestLine).getMethod());
|
|
DebugLog(<< "type code: " << mMsgTypeCode.first << " : " << mMsgTypeCode.second);
|
|
|
|
bool r = (msg->header(h_RequestLine).getMethod() == mMsgTypeCode.first &&
|
|
mMsgTypeCode.second == 0);
|
|
if (!r)
|
|
{
|
|
DebugLog(<< "isMatch failed on method.");
|
|
}
|
|
return r;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::SipExpect::explainMismatch(std::shared_ptr<Event> event) const
|
|
{
|
|
SipEvent* sipEvent = dynamic_cast<SipEvent*>(event.get());
|
|
resip_assert(sipEvent);
|
|
std::shared_ptr<SipMessage> msg = sipEvent->getMessage();
|
|
|
|
Data s;
|
|
{
|
|
DataStream str(s);
|
|
str << "Failed expect: received " << msg->brief()
|
|
<< " for " << msg->header(h_To).uri().user()
|
|
<< " expected " << getMsgTypeString()
|
|
<< " user=" << *sipEvent->getEndPoint();
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
TestSipEndPoint::SipExpect::Exception::Exception(const resip::Data& msg,
|
|
const resip::Data& file,
|
|
const int line)
|
|
: resip::BaseException(msg, file, line)
|
|
{
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::SipExpect::Exception::getName() const
|
|
{
|
|
return "TestEndPoint::Expect::Exception";
|
|
}
|
|
|
|
const char*
|
|
TestSipEndPoint::SipExpect::Exception::name() const noexcept
|
|
{
|
|
return "TestEndPoint::Expect::Exception";
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::buildFdSet(FdSet& fdset)
|
|
{
|
|
resip_assert(mTransport);
|
|
mTransport->buildFdSet(fdset);
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::process(FdSet& fdset)
|
|
{
|
|
mTransport->process(fdset);
|
|
|
|
try
|
|
{
|
|
if (mIncoming.messageAvailable())
|
|
{
|
|
Message* msg = mIncoming.getNext();
|
|
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
|
|
if (sip)
|
|
{
|
|
DebugLog ( << getName() << ":" << getPort() << " got message: " << sip->brief());
|
|
std::shared_ptr<SipMessage> sipMsg(sip);
|
|
handleEvent(std::make_shared<SipEvent>(this, sipMsg));
|
|
}
|
|
else
|
|
{
|
|
delete msg;
|
|
}
|
|
}
|
|
}
|
|
catch (SipExpect::Exception& e)
|
|
{
|
|
DebugLog(<< "Caught: " << e);
|
|
{
|
|
std::shared_ptr<SequenceSet> sset(getSequenceSet());
|
|
if (sset)
|
|
{
|
|
Data msg;
|
|
{
|
|
DataStream str(msg);
|
|
str << e;
|
|
}
|
|
sset->globalFailure(msg);
|
|
}
|
|
}
|
|
}
|
|
catch (resip::BaseException& e)
|
|
{
|
|
DebugLog (<< "Uncaught VOCAL exception: " << e << "...ignoring");
|
|
|
|
std::shared_ptr<SequenceSet> sset(getSequenceSet());
|
|
if (sset)
|
|
{
|
|
Data msg;
|
|
{
|
|
DataStream str(msg);
|
|
str << e;
|
|
}
|
|
sset->globalFailure(msg);
|
|
}
|
|
}
|
|
catch (std::exception& e)
|
|
{
|
|
DebugLog (<< "Uncaught std::exception exception: " << e.what() << "...ignoring");
|
|
|
|
std::shared_ptr<SequenceSet> sset(getSequenceSet());
|
|
if (sset)
|
|
{
|
|
sset->globalFailure(e.what());
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
DebugLog (<< "Uncaught unknown exception ");
|
|
std::shared_ptr<SequenceSet> sset(getSequenceSet());
|
|
if (sset)
|
|
{
|
|
sset->globalFailure("Uncaught unknown exception ");
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::handleEvent(std::shared_ptr<Event> event)
|
|
{
|
|
std::shared_ptr<SipEvent> sipEvent = std::dynamic_pointer_cast<SipEvent>(event);
|
|
resip_assert(sipEvent);
|
|
std::shared_ptr<SipMessage> msg = sipEvent->getMessage();
|
|
mLastMessage = msg;
|
|
|
|
DebugLog(<< getContact() << " is handling: " << *msg);
|
|
if (msg->isResponse())
|
|
{
|
|
if (msg->header(h_CSeq).method() == INVITE &&
|
|
msg->header(h_StatusLine).responseCode() > 100 &&
|
|
msg->header(h_StatusLine).responseCode() <= 200)
|
|
{
|
|
std::shared_ptr<SipMessage> invite = getSentInvite(msg->header(h_CallId));
|
|
//DebugLog (<< "invite map = " << mInvitesSent);
|
|
|
|
// If this is a reliable provisional, then store the sequence numbers for insertion into
|
|
// the result PRACK message
|
|
if (msg->exists(h_RSeq))
|
|
{
|
|
// store state about the provisional if reliable
|
|
mRelRespInfo.rSequence() = (unsigned int) msg->header(h_RSeq).value();
|
|
mRelRespInfo.cSequence() = msg->header(h_CSeq).sequence();
|
|
mRelRespInfo.method() = msg->header(h_CSeq).method();
|
|
}
|
|
|
|
resip_assert(invite != 0);
|
|
|
|
DeprecatedDialog* dialog = getDialog(msg->header(h_CallId),
|
|
msg->header(h_To).param(p_tag));
|
|
if (dialog != 0)
|
|
{
|
|
dialog->targetRefreshResponse(*msg);
|
|
}
|
|
else
|
|
{
|
|
DebugLog (<< "received response in UAS: " << *msg);
|
|
DebugLog (<< "original invite: " << *invite);
|
|
|
|
dialog = new DeprecatedDialog(getContact());
|
|
DebugLog(<<"Creating dialog as UAC from: " << getContact());
|
|
dialog->createDialogAsUAC(*msg);
|
|
DebugLog(<<"Created dialog as UAC from: " << getContact() << ", to: " << dialog->getRemoteTarget());
|
|
mDialogs.push_back(dialog);
|
|
}
|
|
}
|
|
if (msg->header(h_CSeq).method() == SUBSCRIBE &&
|
|
msg->header(h_StatusLine).responseCode()/100 == 2)
|
|
{
|
|
//CerrLog(<< "handling SUBSCRIBE/2xx");
|
|
bool found = false;
|
|
for (SentSubscribeList::iterator i = mSubscribesSent.begin();
|
|
i != mSubscribesSent.end(); ++i)
|
|
{
|
|
if (i->isMatch(msg))
|
|
{
|
|
found = true;
|
|
i->dispatch(msg);
|
|
break;
|
|
}
|
|
}
|
|
if (!found)
|
|
{
|
|
CritLog(<< "no DialogSet for " << *msg);
|
|
}
|
|
resip_assert(found);
|
|
|
|
std::shared_ptr<SipMessage> subscribe = getSentSubscribe(msg);
|
|
resip_assert(subscribe != 0);
|
|
|
|
DeprecatedDialog* dialog = getDialog(msg->header(h_CallId),
|
|
msg->header(h_To).param(p_tag));
|
|
if (dialog != 0)
|
|
{
|
|
DebugLog(<< "refreshing with SUBSCRIBE/2xx"); // not an error
|
|
dialog->targetRefreshResponse(*msg);
|
|
}
|
|
else
|
|
{
|
|
dialog = new DeprecatedDialog(getContact());
|
|
dialog->createDialogAsUAC(*msg);
|
|
DebugLog(<<"Created dialog as UAC from: " << getContact() << ", to: " << dialog->getRemoteTarget());
|
|
mDialogs.push_back(dialog);
|
|
}
|
|
}
|
|
}
|
|
else if (msg->isRequest())
|
|
{
|
|
if (msg->exists(h_Vias) &&
|
|
!msg->header(h_Vias).empty() &&
|
|
msg->header(h_Vias).front().exists(p_branch))
|
|
{
|
|
mRequests[msg->header(h_Vias).front().param(p_branch).getTransactionId()] = msg;
|
|
}
|
|
|
|
if (msg->header(h_RequestLine).getMethod() == INVITE)
|
|
{
|
|
storeReceivedInvite(msg);
|
|
DeprecatedDialog* dialog = getDialog(msg->header(h_CallId),
|
|
msg->header(h_From).param(p_tag));
|
|
if (dialog != 0)
|
|
{
|
|
if (dialog->targetRefreshRequest(*msg) != 0)
|
|
{
|
|
throw GlobalFailure("Target refresh failed", __FILE__, __LINE__);
|
|
}
|
|
}
|
|
}
|
|
if (msg->header(h_RequestLine).getMethod() == UPDATE)
|
|
{
|
|
storeReceivedUpdate(msg);
|
|
DeprecatedDialog* dialog = getDialog(msg->header(h_CallId),
|
|
msg->header(h_From).param(p_tag));
|
|
if (dialog != 0)
|
|
{
|
|
if (dialog->targetRefreshRequest(*msg) != 0)
|
|
{
|
|
throw GlobalFailure("Target refresh failed", __FILE__, __LINE__);
|
|
}
|
|
}
|
|
}
|
|
else if (msg->header(h_RequestLine).getMethod() == SUBSCRIBE)
|
|
{
|
|
storeReceivedSubscribe(msg);
|
|
DeprecatedDialog* dialog = getDialog(msg->header(h_CallId),
|
|
msg->header(h_From).param(p_tag));
|
|
if (dialog != 0)
|
|
{
|
|
if (dialog->targetRefreshRequest(*msg) != 0)
|
|
{
|
|
throw GlobalFailure("Target refresh failed", __FILE__, __LINE__);
|
|
}
|
|
}
|
|
}
|
|
else if (msg->header(h_RequestLine).getMethod() == PUBLISH)
|
|
{
|
|
storeReceivedPublish(msg);
|
|
DeprecatedDialog* dialog = getDialog(msg->header(h_CallId),
|
|
msg->header(h_From).param(p_tag));
|
|
if (dialog != 0)
|
|
{
|
|
if (dialog->targetRefreshRequest(*msg) != 0)
|
|
{
|
|
throw GlobalFailure("Target refresh failed", __FILE__, __LINE__);
|
|
}
|
|
}
|
|
}
|
|
else if (msg->header(h_RequestLine).getMethod() == NOTIFY)
|
|
{
|
|
// find SUBSCRIPTION by CallId (+ localtag eventually), match or create Dialog, update dialog
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugLog(<<"Unknown message type: " << *msg);
|
|
throw GlobalFailure("Unknown msg type", __FILE__, __LINE__);
|
|
}
|
|
std::shared_ptr<SequenceSet> sset(getSequenceSet());
|
|
if (sset)
|
|
{
|
|
sset->enqueue(event);
|
|
}
|
|
else
|
|
{
|
|
WarningLog(<< *this << " has no associated SequenceSet: discarding event " << *event);
|
|
}
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::getName() const
|
|
{
|
|
return mAor.user();
|
|
}
|
|
|
|
int
|
|
TestSipEndPoint::getPort() const
|
|
{
|
|
return mContact.uri().port();
|
|
}
|
|
|
|
const resip::NameAddr&
|
|
TestSipEndPoint::getContact() const
|
|
{
|
|
return mContact;
|
|
}
|
|
|
|
const std::set<resip::NameAddr>&
|
|
TestSipEndPoint::getDefaultContacts() const
|
|
{
|
|
return mContactSet;
|
|
}
|
|
|
|
const resip::Uri&
|
|
TestSipEndPoint::getAddressOfRecord() const
|
|
{
|
|
return mAor;
|
|
}
|
|
|
|
const resip::Uri&
|
|
TestSipEndPoint::getUri() const
|
|
{
|
|
return mAor;
|
|
}
|
|
|
|
resip::Data
|
|
TestSipEndPoint::getAddressOfRecordString() const
|
|
{
|
|
return mAor.getAor();
|
|
}
|
|
|
|
TestSipEndPoint::SaveMatcher*
|
|
saveMatcher(TestSipEndPoint::Matcher* matcher, std::shared_ptr<SipMessage>& msg)
|
|
{
|
|
return new TestSipEndPoint::SaveMatcher(matcher, msg);
|
|
}
|
|
|
|
TestSipEndPoint::From*
|
|
from(const TestSipEndPoint& testEndPoint)
|
|
{
|
|
return new TestSipEndPoint::From(testEndPoint);
|
|
}
|
|
|
|
TestSipEndPoint::From*
|
|
from(TestProxy& testProxy)
|
|
{
|
|
return new TestSipEndPoint::From(testProxy);
|
|
}
|
|
|
|
TestSipEndPoint::From*
|
|
from(const Uri& contact)
|
|
{
|
|
return new TestSipEndPoint::From(contact);
|
|
}
|
|
|
|
TestSipEndPoint::From*
|
|
from(const NameAddr& contact)
|
|
{
|
|
return new TestSipEndPoint::From(contact.uri());
|
|
}
|
|
|
|
TestSipEndPoint::From*
|
|
from(const TestSipEndPoint* testEndPoint)
|
|
{
|
|
resip_assert (testEndPoint);
|
|
return new TestSipEndPoint::From(*testEndPoint);
|
|
}
|
|
|
|
TestSipEndPoint::From*
|
|
from(TestProxy* testProxy)
|
|
{
|
|
return new TestSipEndPoint::From(*testProxy);
|
|
}
|
|
|
|
TestSipEndPoint::From*
|
|
from(const resip::Data& instanceId)
|
|
{
|
|
return new TestSipEndPoint::From(instanceId);
|
|
}
|
|
|
|
TestSipEndPoint::AlwaysMatches*
|
|
alwaysMatches()
|
|
{
|
|
return new TestSipEndPoint::AlwaysMatches;
|
|
}
|
|
|
|
bool
|
|
TestSipEndPoint::MatchNonceCount::isMatch(std::shared_ptr<resip::SipMessage>& message) const
|
|
{
|
|
if (message->isRequest())
|
|
{
|
|
Auth* checkAgainst = 0;
|
|
if (message->exists(h_Authorizations))
|
|
{
|
|
checkAgainst = &message->header(h_Authorizations).front();
|
|
}
|
|
else if (message->exists(h_ProxyAuthorizations))
|
|
{
|
|
checkAgainst = &message->header(h_ProxyAuthorizations).front();
|
|
}
|
|
if (checkAgainst && checkAgainst->exists(p_nc))
|
|
{
|
|
bool ret = checkAgainst->param(p_nc).convertInt() == mCount;
|
|
InfoLog(<< "TestSipEndPoint::MatchNonceCount expected: " << mCount << " "
|
|
<< "got: " << checkAgainst->param(p_nc) << " returning " << ret);
|
|
return ret;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Data
|
|
TestSipEndPoint::MatchNonceCount::toString() const
|
|
{
|
|
Data ret;
|
|
{
|
|
DataStream ds(ret);
|
|
ds << "MatchNonceCount " << mCount;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
TestSipEndPoint::MessageAction*
|
|
condition(TestSipEndPoint::MessageConditionerFn fn, TestSipEndPoint::MessageAction* action)
|
|
{
|
|
action->setConditioner(fn);
|
|
return action;
|
|
}
|
|
|
|
TestSipEndPoint::MessageAction*
|
|
rawcondition(TestSipEndPoint::RawConditionerFn fn, TestSipEndPoint::MessageAction* action)
|
|
{
|
|
action->setRawConditioner(fn);
|
|
return action;
|
|
}
|
|
|
|
TestSipEndPoint::RawSend*
|
|
rawcondition(TestSipEndPoint::RawConditionerFn fn, TestSipEndPoint::RawSend* raw)
|
|
{
|
|
raw->setRawConditioner(fn);
|
|
return raw;
|
|
}
|
|
|
|
TestSipEndPoint::MessageAction*
|
|
save(std::shared_ptr<resip::SipMessage>& msgPtr,
|
|
TestSipEndPoint::MessageAction* action)
|
|
{
|
|
TestSipEndPoint::SaveMessage saver(msgPtr);
|
|
return condition(saver, action);
|
|
}
|
|
|
|
TestSipEndPoint::MessageAction*
|
|
operator<=(std::shared_ptr<resip::SipMessage>& msgPtr, TestSipEndPoint::MessageAction* action)
|
|
{
|
|
return save(msgPtr, action);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
condition(TestSipEndPoint::MessageConditionerFn fn, TestSipEndPoint::MessageExpectAction* action)
|
|
{
|
|
action->setConditioner(fn);
|
|
return action;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
rawcondition(TestSipEndPoint::RawConditionerFn fn, TestSipEndPoint::MessageExpectAction* action)
|
|
{
|
|
action->setRawConditioner(fn);
|
|
return action;
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
save(std::shared_ptr<resip::SipMessage>& msgPtr,
|
|
TestSipEndPoint::MessageExpectAction* action)
|
|
{
|
|
TestSipEndPoint::SaveMessage saver(msgPtr);
|
|
return condition(saver, action);
|
|
}
|
|
|
|
OptionTagConditioner::OptionTagConditioner(const resip::Tokens& tags, Location loc) :
|
|
mTags(tags),
|
|
mLocation(loc)
|
|
{}
|
|
|
|
std::shared_ptr<resip::SipMessage>
|
|
OptionTagConditioner::operator()(std::shared_ptr<resip::SipMessage> msg)
|
|
{
|
|
switch(mLocation)
|
|
{
|
|
case Supported:
|
|
copy(mTags.begin(), mTags.end(), back_insert_iterator<Tokens>(msg->header(h_Supporteds)));
|
|
break;
|
|
case Required:
|
|
copy(mTags.begin(), mTags.end(), back_insert_iterator<Tokens>(msg->header(h_Requires)));
|
|
break;
|
|
default:
|
|
resip_assert(0);
|
|
}
|
|
return msg;
|
|
}
|
|
|
|
TestSipEndPoint::MessageAction*
|
|
addSupported(const resip::Tokens& tokens, TestSipEndPoint::MessageAction* action)
|
|
{
|
|
return condition(OptionTagConditioner(tokens, OptionTagConditioner::Supported), action);
|
|
}
|
|
|
|
TestSipEndPoint::MessageAction*
|
|
addSupported(const resip::Data& tag, TestSipEndPoint::MessageAction* action)
|
|
{
|
|
resip::Tokens t;
|
|
t.push_back(resip::Token(tag));
|
|
return condition(OptionTagConditioner(t, OptionTagConditioner::Supported), action);
|
|
}
|
|
|
|
TestSipEndPoint::MessageAction*
|
|
addRequired(const resip::Tokens& tokens, TestSipEndPoint::MessageAction* action)
|
|
{
|
|
return condition(OptionTagConditioner(tokens, OptionTagConditioner::Required), action);
|
|
}
|
|
|
|
TestSipEndPoint::MessageAction*
|
|
addRequired(const resip::Data& tag, TestSipEndPoint::MessageAction* action)
|
|
{
|
|
resip::Tokens t;
|
|
t.push_back(resip::Token(tag));
|
|
return condition(OptionTagConditioner(t, OptionTagConditioner::Required), action);
|
|
}
|
|
|
|
TestSipEndPoint::MessageExpectAction*
|
|
operator<=(std::shared_ptr<resip::SipMessage>& msgPtr, TestSipEndPoint::MessageExpectAction* action)
|
|
{
|
|
return save(msgPtr, action);
|
|
}
|
|
|
|
TestEndPoint::ExpectBase*
|
|
TestSipEndPoint::expect(MethodTypes msgType, Matcher* matcher, int timeoutMs, ActionBase* expectAction)
|
|
{
|
|
return new SipExpect(*this, make_pair(msgType, 0), matcher, *TestEndPoint::AlwaysTruePred, timeoutMs, expectAction);
|
|
}
|
|
|
|
TestEndPoint::ExpectBase*
|
|
TestSipEndPoint::expect(MethodTypes msgType, Matcher* matcher, ExpectPreCon& pred, int timeoutMs, ActionBase* expectAction)
|
|
{
|
|
return new SipExpect(*this, make_pair(msgType, 0), matcher, pred, timeoutMs, expectAction);
|
|
}
|
|
|
|
TestEndPoint::ExpectBase*
|
|
TestSipEndPoint::expect(pair<MethodTypes, int> msgTypeCode, Matcher* matcher, int timeoutMs, ActionBase* expectAction)
|
|
{
|
|
return new SipExpect(*this, msgTypeCode, matcher, *TestEndPoint::AlwaysTruePred, timeoutMs, expectAction);
|
|
}
|
|
|
|
TestEndPoint::ExpectBase*
|
|
TestSipEndPoint::expect(pair<MethodTypes, int> msgTypeCode, Matcher* matcher, ExpectPreCon& pred, int timeoutMs, ActionBase* expectAction)
|
|
{
|
|
return new SipExpect(*this, msgTypeCode, matcher, pred, timeoutMs, expectAction);
|
|
}
|
|
|
|
Box
|
|
TestSipEndPoint::SipExpect::layout() const
|
|
{
|
|
mBox.mX = 1;
|
|
mBox.mY = 0;
|
|
|
|
// |
|
|
// ext17->100
|
|
mBox.mHeight = 2;
|
|
|
|
Data out;
|
|
{
|
|
DataStream str(out);
|
|
bool previousActive = false;
|
|
prettyPrint(str, previousActive, 0);
|
|
}
|
|
mBox.mWidth = (unsigned int)out.size()+2;
|
|
|
|
//InfoLog(<< "TestSipEndPoint::SipExpect::layout: " << mBox);
|
|
|
|
return mBox;
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::SipExpect::render(CharRaster& out) const
|
|
{
|
|
//InfoLog(<< "TestSipEndPoint::SipExpect::render");
|
|
out[mBox.mY][mBox.mX + mBox.mWidth/2] = '|';
|
|
|
|
Data s(" ");
|
|
{
|
|
DataStream str(s);
|
|
|
|
bool previousActive = false;
|
|
prettyPrint(str, previousActive, 0);
|
|
}
|
|
s += " ";
|
|
|
|
//InfoLog(<< "size of SipExpect::render size = " << s.size());
|
|
int x = 0;
|
|
for (unsigned int i=0; i<s.size(); i++)
|
|
{
|
|
out[mBox.mY+1][mBox.mX + x] = s[i];
|
|
x++;
|
|
}
|
|
}
|
|
|
|
std::pair<resip::MethodTypes, int>
|
|
operator/(resip::MethodTypes meth,
|
|
int code)
|
|
{
|
|
return std::make_pair(meth, code);
|
|
}
|
|
|
|
TestSipEndPoint::MessageConditionerFn
|
|
compose(TestSipEndPoint::MessageConditionerFn fn2,
|
|
TestSipEndPoint::MessageConditionerFn fn1)
|
|
{
|
|
return TestSipEndPoint::ChainConditions(fn2, fn1);
|
|
}
|
|
|
|
TestSipEndPoint::MessageConditionerFn
|
|
compose(TestSipEndPoint::MessageConditionerFn fn3,
|
|
TestSipEndPoint::MessageConditionerFn fn2,
|
|
TestSipEndPoint::MessageConditionerFn fn1)
|
|
{
|
|
return compose(fn3, compose(fn2, fn1));
|
|
}
|
|
|
|
TestSipEndPoint::MessageConditionerFn
|
|
compose(TestSipEndPoint::MessageConditionerFn fn4,
|
|
TestSipEndPoint::MessageConditionerFn fn3,
|
|
TestSipEndPoint::MessageConditionerFn fn2,
|
|
TestSipEndPoint::MessageConditionerFn fn1)
|
|
{
|
|
return compose(fn4, compose(fn3, compose(fn2, fn1)));
|
|
}
|
|
|
|
|
|
TestSipEndPoint::RawConditionerFn
|
|
rawcompose(TestSipEndPoint::RawConditionerFn fn2,
|
|
TestSipEndPoint::RawConditionerFn fn1)
|
|
{
|
|
return TestSipEndPoint::ChainRawConditions(fn2, fn1);
|
|
}
|
|
|
|
TestSipEndPoint::RawConditionerFn
|
|
rawcompose(TestSipEndPoint::RawConditionerFn fn3,
|
|
TestSipEndPoint::RawConditionerFn fn2,
|
|
TestSipEndPoint::RawConditionerFn fn1)
|
|
{
|
|
return rawcompose(fn3, rawcompose(fn2, fn1));
|
|
}
|
|
|
|
TestSipEndPoint::RawConditionerFn
|
|
rawcompose(TestSipEndPoint::RawConditionerFn fn4,
|
|
TestSipEndPoint::RawConditionerFn fn3,
|
|
TestSipEndPoint::RawConditionerFn fn2,
|
|
TestSipEndPoint::RawConditionerFn fn1)
|
|
{
|
|
return rawcompose(fn4, rawcompose(fn3, rawcompose(fn2, fn1)));
|
|
}
|
|
|
|
|
|
#ifdef RTP_ON
|
|
void
|
|
TestSipEndPoint::CreateRtpSession::operator()(std::shared_ptr<Event> event)
|
|
{
|
|
SipEvent* sipEvent = dynamic_cast<SipEvent*>(event.get());
|
|
resip_assert(sipEvent);
|
|
shared_ptr<SipMessage> msg = sipEvent->getMessage();
|
|
|
|
SdpContents* remoteSdp = dynamic_cast<SdpContents*>(msg->getContents());
|
|
resip_assert(remoteSdp != 0);
|
|
|
|
resip_assert(!_localSdp->session().getMedia().empty());
|
|
resip_assert(!remoteSdp->session().getMedia().empty());
|
|
|
|
int localPort = _localSdp->session().getMedia().front().getPort();
|
|
int remotePort = remoteSdp->session().getMedia().front().getPort();
|
|
|
|
resip::Data rmtSdpAddr = remoteSdp->session().getOrigin().getAddress();
|
|
|
|
mEndPoint->mRtpSession = new RtpSession( rmtSdpAddr.c_str(),
|
|
remotePort,
|
|
localPort,
|
|
0,0,
|
|
rtpPayloadPCMU,
|
|
rtpPayloadPCMU,-1 );
|
|
}
|
|
resip::Data
|
|
TestSipEndPoint::CreateRtpSession::toString() const
|
|
{
|
|
return mEndPoint->getName() + ".createRtpSession()";
|
|
}
|
|
|
|
|
|
TestSipEndPoint::SendDtmf::SendDtmf(TestSipEndPoint* endPoint, const DtmfSequence& dtmfString)
|
|
: mEndPoint(endPoint)
|
|
{
|
|
ActionBase* endOfChain = 0;
|
|
ActionBase* startOfChain = 0;
|
|
for ( unsigned int i=0; i < dtmfString.size(); i++ )
|
|
{
|
|
int dtmfDigit;
|
|
switch(dtmfString[i].first)
|
|
{
|
|
case '*' : dtmfDigit = 10; break;
|
|
case '#' : dtmfDigit = 11; break;
|
|
default : dtmfDigit = (int)(dtmfString[i].first - '0');
|
|
}
|
|
|
|
SendDtmfChar* s = new SendDtmfChar(mEndPoint, dtmfDigit);
|
|
Pause* p = new Pause(dtmfString[i].second, mEndPoint);
|
|
|
|
s->addNext(p);
|
|
if (endOfChain != 0)
|
|
{
|
|
endOfChain->addNext(s);
|
|
startOfChain = s;
|
|
}
|
|
endOfChain = p;
|
|
}
|
|
this->addNext(startOfChain);
|
|
}
|
|
|
|
void
|
|
TestSipEndPoint::SendDtmf::operator()(std::shared_ptr<Event> event)
|
|
{}
|
|
|
|
void
|
|
TestSipEndPoint::SendDtmf::SendDtmfChar::operator()(TestSipEndPoint& endPoint)
|
|
{
|
|
RtpPacket *pkt = mEndPoint->mRtpSession->receive();
|
|
if (pkt)
|
|
{
|
|
DebugLog(<<"Received Rtp Packet");
|
|
delete pkt;
|
|
pkt = 0;
|
|
}
|
|
|
|
if(_dtmf >= 0 && _dtmf <= 11)
|
|
{
|
|
mEndPoint->mRtpSession->transmitEvent(_dtmf);
|
|
DebugLog(<<"Sending: " << _dtmf << " via DTMF");
|
|
}
|
|
}
|
|
|
|
#endif // RTP_ON
|
|
|
|
#if 0
|
|
std::shared_ptr<SdpContents>
|
|
TestSipEndPoint::MakeSdp(const Data& user,
|
|
const Data& hostname,
|
|
int port,
|
|
const Data& codec)
|
|
{
|
|
auto sdp = std::make_shared<SdpContents>();
|
|
|
|
sdp->session().version() = 0;
|
|
sdp->session().origin().user() = user;
|
|
sdp->session().origin().setAddress(hostname);
|
|
sdp->session().name() = "-";
|
|
|
|
SdpContents::Session::Medium medium;
|
|
medium.port() = port;
|
|
|
|
medium.setConnection(SdpContents::Session::Connection(SdpContents::IP4, hostname));
|
|
sdp->session().addMedium(medium);
|
|
|
|
return sdp;
|
|
}
|
|
#endif
|
|
|
|
// Copyright 2005 Purplecomm, Inc.
|
|
/*
|
|
Copyright (c) 2005, PurpleComm, Inc.
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
are permitted provided that the following conditions are met:
|
|
|
|
* Redistributions of source code must retain the above copyright notice, this
|
|
list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
* Neither the name of PurpleComm, Inc. nor the names of its contributors may
|
|
be used to endorse or promote products derived from this software without
|
|
specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|