1#if defined(HAVE_CONFIG_H)
17#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
21 : mContact(localContact),
44 if ( (!mCreated) && (code < 300) && (code > 100) )
56 if (request.
exists(h_RecordRoutes))
58 mRouteSet = request.
header(h_RecordRoutes);
61 if (!request.
exists(h_Contacts) && request.
header(h_Contacts).size() != 1)
63 InfoLog (<<
"Request doesn't have a contact header or more than one contact, so can't create dialog");
65 throw Exception(
"Invalid or missing contact header in request", __FILE__,__LINE__);
68 mRemoteTarget = request.
header(h_Contacts).front();
69 mRemoteSequence = request.
header(h_CSeq).sequence();
76 mLocalTag = response->
header(h_To).param(p_tag);
77 if (request.
header(h_From).exists(p_tag))
79 mRemoteTag = request.
header(h_From).param(p_tag);
82 mRemoteUri = request.
header(h_From);
83 mLocalUri = request.
header(h_To);
86 mDialogId.
param(p_toTag) = mLocalTag;
87 mDialogId.
param(p_fromTag) = mRemoteTag;
89 mEarly = (code < 200);
99 response->
header(h_To).param(p_tag) = mLocalTag;
117 mEarly = (code > 100 && code < 200);
119 if (code >= 200 && code < 300)
121 if (!response.
exists(h_Contacts) || response.
header(h_Contacts).size() != 1)
123 InfoLog (<<
"Response doesn't have a contact header or more than one contact, so can't create dialog");
125 throw Exception(
"Invalid or missing contact header in message", __FILE__,__LINE__);
130 if (response.
exists(h_RecordRoutes))
132 mRouteSet = response.
header(h_RecordRoutes).reverse();
135 if (response.
exists(h_Contacts) && !response.
header(h_Contacts).empty())
137 mRemoteTarget = response.
header(h_Contacts).front();
142 mLocalSequence = response.
header(h_CSeq).sequence();
145 if ( response.
header(h_From).exists(p_tag) )
147 mLocalTag = response.
header(h_From).param(p_tag);
149 if ( response.
header(h_To).exists(p_tag) )
151 mRemoteTag = response.
header(h_To).param(p_tag);
153 mRemoteUri = response.
header(h_To);
154 mLocalUri = response.
header(h_From);
157 mDialogId.
param(p_toTag) = mLocalTag;
158 mDialogId.
param(p_fromTag) = mRemoteTag;
165 if (notify.
exists(h_RecordRoutes))
167 mRouteSet = notify.
header(h_RecordRoutes);
170 if (!notify.
exists(h_Contacts) && notify.
header(h_Contacts).size() != 1)
172 InfoLog (<<
"Notify doesn't have a contact header or more than one contact, so can't create dialog");
174 throw Exception(
"Invalid or missing contact header in notify", __FILE__,__LINE__);
177 mRemoteTarget = notify.
header(h_Contacts).front();
178 mRemoteSequence = notify.
header(h_CSeq).sequence();
179 mRemoteEmpty =
false;
183 if (notify.
header(h_To).exists(p_tag))
185 mLocalTag = notify.
header(h_To).param(p_tag);
187 if (notify.
header(h_From).exists(p_tag))
189 mRemoteTag = notify.
header(h_From).param(p_tag);
192 mRemoteUri = notify.
header(h_From);
193 mLocalUri = notify.
header(h_To);
196 mDialogId.
param(p_toTag) = mLocalTag;
197 mDialogId.
param(p_fromTag) = mRemoteTag;
219 if (response.
exists(h_Contacts) && response.
header(h_Contacts).size() == 1)
221 mRemoteTarget = response.
header(h_Contacts).front();
231 unsigned long cseq = request.
header(h_CSeq).sequence();
235 mRemoteSequence = cseq;
236 mRemoteEmpty =
false;
238 else if (cseq < mRemoteSequence)
240 InfoLog (<<
"Got a cseq out of sequence: " << cseq <<
" < " << mRemoteSequence);
241 throw Exception(
"out of order", __FILE__,__LINE__);
245 mRemoteSequence = cseq;
248 if (request.
exists(h_Contacts) && request.
header(h_Contacts).size() == 1)
250 mRemoteTarget = request.
header(h_Contacts).front();
254 InfoLog (<<
"Request doesn't have a contact header or more than one contact, so can't create dialog");
256 throw Exception(
"Invalid or missing contact header in message", __FILE__,__LINE__);
270 request.
header(h_To) = mRemoteUri;
271 if ( !mRemoteTag.
empty() )
273 request.
header(h_To).param(p_tag) = mRemoteTag;
275 request.
header(h_From) = mLocalUri;
276 if ( !mLocalTag.
empty() )
278 request.
header(h_From).param(p_tag) = mLocalTag;
281 request.
header(h_Routes) = mRouteSet;
283 request.
header(h_Contacts).push_back(mContact);
285 incrementCSeq(request);
287 request.
header(h_MaxForwards).value() = 70;
292 request.
header(h_Vias).push_back(via);
299 DebugLog (<<
"Updating a request when not in a dialog yet");
307 if ( (!mCreated) && (code < 300) && (code > 100) )
316 if (request.
exists(h_RecordRoutes))
318 mRouteSet = request.
header(h_RecordRoutes);
321 if (!request.
exists(h_Contacts) && request.
header(h_Contacts).size() != 1)
323 InfoLog (<<
"Request doesn't have a contact header or more than one contact, so can't create dialog");
325 throw Exception(
"Invalid or missing contact header in request", __FILE__,__LINE__);
328 mRemoteTarget = request.
header(h_Contacts).front();
329 mRemoteSequence = request.
header(h_CSeq).sequence();
330 mRemoteEmpty =
false;
335 mLocalTag = response.
header(h_To).param(p_tag);
336 if (request.
header(h_From).exists(p_tag))
338 mRemoteTag = request.
header(h_From).param(p_tag);
341 mRemoteUri = request.
header(h_From);
342 mLocalUri = request.
header(h_To);
345 mDialogId.
param(p_toTag) = mLocalTag;
346 mDialogId.
param(p_fromTag) = mRemoteTag;
348 mEarly = (code > 100 && code < 200);
357 response.
header(h_To).param(p_tag) = mLocalTag;
380 mRemoteTarget = mRemoteUri;
465 SipMessage* request = makeRequestInternal(INVITE);
466 incrementCSeq(*request);
467 DebugLog(<<
"DeprecatedDialog::makeInvite: " << *request);
474 SipMessage* request = makeRequestInternal(UPDATE);
475 incrementCSeq(*request);
476 DebugLog(<<
"DeprecatedDialog::makeUpdate: " << *request);
483 SipMessage* request = makeRequestInternal(REGISTER);
484 incrementCSeq(*request);
485 DebugLog(<<
"DeprecatedDialog::makeRegister: " << *request);
492 SipMessage* request = makeRequestInternal(SUBSCRIBE);
493 incrementCSeq(*request);
494 DebugLog(<<
"DeprecatedDialog::makeSubscribe: " << *request);
501 SipMessage* request = makeRequestInternal(BYE);
502 incrementCSeq(*request);
511 SipMessage* request = makeRequestInternal(REFER);
512 request->
header(h_ReferTo) = referTo;
513 request->
header(h_ReferredBy) = mLocalUri;
514 incrementCSeq(*request);
521 SipMessage* request = makeRequestInternal(NOTIFY);
522 incrementCSeq(*request);
530 SipMessage* request = makeRequestInternal(OPTIONS);
531 incrementCSeq(*request);
538 SipMessage* request = makeRequestInternal(PUBLISH);
539 incrementCSeq(*request);
549 SipMessage* request = makeRequestInternal(method);
550 incrementCSeq(*request);
557 SipMessage* request = makeRequestInternal(ACK);
564 if (original.
exists(h_ProxyAuthorizations))
566 request->
header(h_ProxyAuthorizations) = original.
header(h_ProxyAuthorizations);
568 if (original.
exists(h_Authorizations))
570 request->
header(h_Authorizations) = original.
header(h_Authorizations);
572 request->
header(h_CSeq).sequence() = original.
header(h_CSeq).sequence();
579 SipMessage* request = makeRequestInternal(ACK);
600 cancel->
header(h_Vias).push_back(request.
header(h_Vias).front());
632DeprecatedDialog::makeRequestInternal(
MethodTypes method)
639 rLine.uri() = mRequestUri;
643 rLine.uri() = mRemoteTarget.
uri();
647 request->
header(h_To) = mRemoteUri;
648 if ( !mRemoteTag.
empty() )
650 request->
header(h_To).param(p_tag) = mRemoteTag;
652 request->
header(h_From) = mLocalUri;
653 if ( !mLocalTag.
empty() )
655 request->
header(h_From).param(p_tag) = mLocalTag;
658 request->
header(h_Routes) = mRouteSet;
659 request->
header(h_Contacts).push_back(mContact);
662 request->
header(h_MaxForwards).value() = 70;
666 request->
header(h_Vias).push_front(via);
673DeprecatedDialog::copyCSeq(
SipMessage& request)
680 request.
header(h_CSeq).sequence() = mLocalSequence;
684DeprecatedDialog::incrementCSeq(
SipMessage& request)
692 request.
header(h_CSeq).sequence() = ++mLocalSequence;
698 strm <<
"DeprecatedDialog: [" << d.
dialogId()
699 <<
" created=" << d.mCreated
700 <<
",remoteTarget=" << d.mRemoteTarget
701 <<
", routeset=" <<
Inserter(d.mRouteSet)
702 <<
",remoteSeq=" << d.mRemoteSequence
703 <<
",remote=" << d.mRemoteUri
704 <<
",remoteTag=" << d.mRemoteTag
705 <<
",localSeq=" << d.mLocalSequence
706 <<
",local=" << d.mLocalUri
707 <<
",localTag=" << d.mLocalTag
719 if (msg.
header(h_To).exists(p_tag))
721 id.param(p_toTag) = msg.
header(h_To).param(p_tag);
723 if (msg.
header(h_From).exists(p_tag))
725 id.param(p_fromTag) = msg.
header(h_From).param(p_tag);
730 if (msg.
header(h_From).exists(p_tag))
732 id.param(p_toTag) = msg.
header(h_From).param(p_tag);
734 if (msg.
header(h_To).exists(p_tag))
736 id.param(p_fromTag) = msg.
header(h_To).param(p_tag);
763 int ret = (int)delta;
#define resip_assert(x)
This file needs to work for both C and C++ code.
Represents the "callid" element in the SIP grammar.
const Data & param(const ExtensionParameter ¶m) const
Const accessor for non-natively-supported parameter types.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
static const Data Empty
Constant that represents a zero-length data.
bool empty() const noexcept
Checks whether the Data is empty.
static Data from(const T &x)
Converts from arbitrary other type to Data.
SipMessage * makeNotify()
const Data dialogId() const
SipMessage * makeInitialInvite(const NameAddr &target, const NameAddr &from)
SipMessage * makeSubscribe()
SipMessage * makeRegister()
SipMessage * makeInitialMessage(const NameAddr &target, const NameAddr &from)
SipMessage * makeInvite()
SipMessage * makeInitialRegister(const NameAddr ®istrar, const NameAddr &from)
SipMessage * makeRequest(MethodTypes method)
static Data dialogId(const SipMessage &msg)
SipMessage * makeUpdate()
SipMessage * makePublish()
SipMessage * makeOptions()
int targetRefreshRequest(const SipMessage &request)
void updateRequest(SipMessage &msg)
SipMessage * makeRefer(const NameAddr &referTo)
void setExpirySeconds(int secondsInFuture)
SipMessage * makeResponse(const SipMessage &request, int code=200)
SipMessage * makeInitialSubscribe(const NameAddr &target, const NameAddr &from)
void createDialogAsUAC(const SipMessage &response)
DeprecatedDialog(const NameAddr &localContact)
SipMessage * makeCancel(const SipMessage &request)
SipMessage * makeInitialPublish(const NameAddr &target, const NameAddr &from)
void targetRefreshResponse(const SipMessage &response)
static const int tagSize
bytes in to-tag& from-tag, should prob. live somewhere else
static SipMessage * makePublish(const NameAddr &target, const NameAddr &from)
Create a Publish request with an empty Contact. See makeRequest.
static SipMessage * makeRegister(const NameAddr &to, const NameAddr &from)
Create a Register request with an empty Contact. See makeRequest.
static SipMessage * makeInvite(const NameAddr &target, const NameAddr &from)
Make an invite request - Empty Contact and Via is added and will be populated by the stack when sent.
static void processStrictRoute(SipMessage &request)
static SipMessage * makeMessage(const NameAddr &target, const NameAddr &from)
Create a Message request with an empty Contact. See makeRequest.
static Data computeTag(int numBytes)
static void makeResponse(SipMessage &response, const SipMessage &request, int responseCode, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty)
Make a response to a provided request.
static SipMessage * makeSubscribe(const NameAddr &target, const NameAddr &from)
Create a Subscribe request with an empty Contact. See makeRequest.
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
void clear()
clear the mParsers vector
Represents the "Request-Line" element in the RFC 3261 grammar.
MethodTypes getMethod() const
Represents a SIP message.
bool isRequest() const
Returns true if message is a request, false otherwise.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
bool isResponse() const
Returns true if message is a response, false otherwise.
const RequestLine & const_header(const RequestLineType &l) const
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
bool isExternal() const
Check if SipMessage is to be treated as it came off the wire.
static uint64_t getTimeMs()
Returns the current clock time in milliseconds.
Represents the "via-parm" element in the RFC 3261 grammar.
const Data & param(const ExtensionParameter ¶m) const
Const accessor for non-natively-supported parameter types.
dcm! – add UnusedChecking(_enum) below;
StatusLineType h_StatusLine
InserterClass< T > Inserter(const T &t)
Templatized function to construct an instance of InserterClass for a container to be inserted.
unsigned long long uint64_t
RequestLineType h_RequestLine
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)