reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
PresenceSubscriptionHandler.cxx
Go to the documentation of this file.
5
11#include <rutil/ResipAssert.h>
12#include <rutil/Logger.hxx>
13
14using namespace repro;
15using namespace resip;
16
17#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
18
20 resip::Dispatcher* userDispatcher,
21 bool presenceUsesRegistrationState,
22 bool presenceNotifyClosedStateForNonPublishedUsers)
25 mDum(dum),
26 mPublicationDb(dynamic_cast<InMemorySyncPubDb*>(dum.getPublicationPersistenceManager())),
27 mRegistrationDb(dynamic_cast<InMemorySyncRegDb*>(dum.getRegistrationPersistenceManager())),
28 mPresenceUsesRegistrationState(presenceUsesRegistrationState),
29 mPresenceNotifyClosedStateForNonPublishedUsers(presenceNotifyClosedStateForNonPublishedUsers),
30 mUserDispatcher(userDispatcher)
31{
35 {
37 }
39}
40
49
50void
52{
53 InfoLog(<< "PresenceSubscriptionHandler::onNewSubscription: msg=" << std::endl << sub);
54 notifyPresence(h, true /* sendAcceptReject? */);
55}
56
58{
59 h->send(h->accept(200));
60
61 // Check to see if registration state changed
63 {
64 Uri aor("sip:" + h->getDocumentKey());
65 uint64_t maxExpires = 0;
66 bool isRegistered = mRegistrationDb->aorIsRegistered(aor, &maxExpires);
67 InfoLog(<< "PresenceSubscriptionHandler::onRefresh: aor=" << aor << ", registered=" << isRegistered << ", maxRegExpires=" << maxExpires);
68 if (!checkRegistrationStateChanged(aor, isRegistered, maxExpires))
69 {
70 auto notify = h->neutralNotify();
71 if (maxExpires && isRegistered)
72 {
73 adjustNotifyExpiresTime(*notify.get(), maxExpires);
74 }
75 h->send(notify);
76 }
77 }
78 else
79 {
80 h->send(h->neutralNotify());
81 }
82}
83
84void
86 ServerPublicationHandle publication,
87 const Contents* contents,
88 const SecurityAttributes* attrs)
89{
90 if (contents)
91 {
92 InfoLog(<< "PresenceSubscriptionHandler::onPublished: docKey=" << associated->getDocumentKey() << ", contents=" << std::endl << *contents);
93 }
94 else
95 {
96 InfoLog(<< "PresenceSubscriptionHandler::onPublished: no contents, docKey=" << associated->getDocumentKey());
97 }
98 // We don't need to call notifyPresence here, since we are subscribed to changes in the InMemorySyncPubDb.
99 // This allows up to notify for PUBLISHes that arrive via a sync operation as well.
100 //notifyPresence(associated, false /* sendAcceptReject? */);
101}
102
103
104void
106{
107 InfoLog(<< "PresenceSubscriptionHandler::onTerminated: docKey=" << h->getDocumentKey());
108}
109
110void
112{
113 InfoLog(<< "PresenceSubscriptionHandler::onError: docKey=" << h->getDocumentKey() << ", msg=" << std::endl << msg);
114}
115
116void
118{
119 try
120 {
121 Uri aor("sip:" + h->getDocumentKey());
123 {
124 DebugLog(<< "PresenceSubscriptionHandler::notifyPresence: attempting to notify published presence for aor=" << aor);
125 if (!sendPublishedPresence(h, sendAcceptReject))
126 {
127 notifyPresenceNoPublication(h, sendAcceptReject, aor, mRegistrationDb->aorIsRegistered(aor), 0 /* maxRegExpires - not needed in this case */);
128 }
129 }
130 else
131 {
132 uint64_t maxExpires = 0;
133 bool isRegistered = mRegistrationDb->aorIsRegistered(aor, &maxExpires);
134 if (isRegistered)
135 {
136 mOnlineAors.insert(aor);
137 DebugLog(<< "PresenceSubscriptionHandler::notifyPresence: attempting to notify published presence for aor=" << aor);
138 if (!sendPublishedPresence(h, sendAcceptReject))
139 {
140 // Fabricate a simple presence update based on registration state
141 fabricateSimplePresence(h, sendAcceptReject, aor, true /* online? */, maxExpires);
142 }
143 }
144 else
145 {
146 notifyPresenceNoPublication(h, sendAcceptReject, aor, isRegistered, maxExpires);
147 }
148 }
149 }
150 catch (BaseException& ex)
151 {
152 ErrLog(<< "PresenceSubscriptionHandler::notifyPresence: problem notifying presence: " << ex);
153 if (sendAcceptReject && h->isResponsePending())
154 {
155 h->send(h->reject(500));
156 }
157 }
158}
159
160void
161PresenceSubscriptionHandler::notifyPresenceNoPublication(resip::ServerSubscriptionHandle h, bool sendAcceptReject, const Uri& aor, bool isRegistered, uint64_t regMaxExpires)
162{
163 DebugLog(<< "PresenceSubscriptionHandler::notifyPresenceNoPublication: no publication for aor=" << aor << ", registered=" << isRegistered);
164 // First we can look in the InMemory Registration database for the user - if they are there, we know they exist
165 // and we don't need to do an async lookup
166 if (isRegistered)
167 {
169 {
170 mOnlineAors.insert(aor);
171 fabricateSimplePresence(h, sendAcceptReject, aor, true /* online? */, regMaxExpires);
172 }
173 else
174 {
175 continueNotifyPresenceAfterUserExistsCheck(h, sendAcceptReject, aor, true /* userExists? */);
176 }
177 }
178 else
179 {
180 mOnlineAors.erase(aor); // remove now, since we might have an immediate unregister coming in before this async finishes and we want to avoid sending 2 closed states
181
182 // Do async lookup of user from User tables
183 PresenceUserExists* async = new PresenceUserExists(mDum, this, h, sendAcceptReject, aor);
184 std::unique_ptr<ApplicationMessage> app(async);
185 mUserDispatcher->post(app);
186 }
187}
188
189void
191{
192 if (mServerSubscriptionHandle.isValid())
193 {
194 mSubscriptionHandler->continueNotifyPresenceAfterUserExistsCheck(mServerSubscriptionHandle, mSendAcceptReject, mAor, mUserExists);
195 }
196}
197
198void
200{
201 DebugLog(<< "PresenceSubscriptionHandler::continueNotifyPresenceAfterUserExistsCheck: aor=" << aor << ", userExists=" << userExists);
203 {
204 if (sendAcceptReject)
205 {
206 if (userExists)
207 {
209 {
210 fabricateSimplePresence(h, sendAcceptReject, aor, false /* online? */, 0 /* regMaxExpires not need in this case */);
211 }
212 else
213 {
214 h->send(h->reject(480));
215 }
216 }
217 else
218 {
219 h->send(h->reject(404));
220 }
221 }
222 else
223 {
225 {
226 fabricateSimplePresence(h, sendAcceptReject, aor, false /* online? */, 0 /* regMaxExpires not need in this case */);
227 }
228 else
229 {
230 h->end(NoResource);
231 }
232 }
233 }
234 else
235 {
236 if (userExists)
237 {
238 mOnlineAors.erase(aor);
239
240 // we only get here if user wasn't registered, so hardcode online to false
241 fabricateSimplePresence(h, sendAcceptReject, aor, false /* online? */, 0 /* regMaxExpires not need in this case */);
242 }
243 else if (sendAcceptReject)
244 {
245 h->send(h->reject(404));
246 }
247 }
248}
249
250bool
252{
254 bool result = mPublicationDb->getMergedETags(h->getEventType(), h->getDocumentKey(), *this, &pidf);
255 if (result)
256 {
257 if (sendAcceptReject)
258 {
260 h->send(h->accept(200));
261 }
262 h->send(h->update(&pidf));
263 }
264 return result;
265}
266
267const uint32_t ReSubGraceTime = 32; // Somewhat arbitrary - using SIP transaction timeout
268void
270{
271 resip_assert(notify.exists(h_SubscriptionState));
272 resip_assert(notify.header(h_SubscriptionState).exists(p_expires));
273
274 // The following is an effort to catch timed out / expired registrations
275 // We are reducing the subscription expiration time to try and get the client to refresh the
276 // subscription soon after the registration may have expired. Since rfc 3261 recommends
277 // refreshing using Helper::aBitSmallerThan logic - we assume the clients will do the same
278 // and we calculate a time using the inverse calculation (including a small grace period).
279 // If the registration does expire without a refresh, then the rebsub should arrive shortly
280 // after and when it does we will check the reg state.
281 // TODO - a better solution would be to implement timers for registration expirations, then
282 // just notify immediately on expiration. However this is not very straight forward
283 // as we must also consider sync'd registrations and need a place to start all these
284 // timers.
285
286 uint32_t timeUntillRegExpires = (uint32_t)(regMaxExpires - Timer::getTimeSecs());
287 // Scale up expiration time used in Notify to be the opposite of aBitSmallerThan + some grace time
288 uint32_t scaledUpTimeSoSubRefreshComesAfter = resipMax(timeUntillRegExpires + 5 + ReSubGraceTime, ((timeUntillRegExpires * 10) / 9) + ReSubGraceTime);
289
290 // RFC3265 - says we can shorten the expiration but not increase it - so using resipMin
291 notify.header(h_SubscriptionState).param(p_expires) = resipMin(scaledUpTimeSoSubRefreshComesAfter, notify.header(h_SubscriptionState).param(p_expires));
292}
293
294void
295PresenceSubscriptionHandler::fabricateSimplePresence(ServerSubscriptionHandle h, bool sendAcceptReject, const resip::Uri& aor, bool online, uint64_t regMaxExpires)
296{
297 InfoLog(<< "PresenceSubscriptionHandler::fabricateSimplePresence: aor=" << aor << ", online=" << online << ", maxRegExpires=" << regMaxExpires);
298
299 // Fabricate a simple presence update based on registration state
301 pidf.setEntity(aor);
303 if (sendAcceptReject)
304 {
306 h->send(h->accept(200));
307 }
308 auto notify = h->update(&pidf);
309 if (regMaxExpires && online)
310 {
311 adjustNotifyExpiresTime(*notify.get(), regMaxExpires);
312 }
313 h->send(notify);
314}
315
316bool
318{
319 GenericPidfContents* destPidf = dynamic_cast<GenericPidfContents*>(eTagDest);
320 GenericPidfContents* srcPidf = dynamic_cast<GenericPidfContents*>(eTagSrc);
321 if (destPidf && srcPidf)
322 {
323 if (isFirst)
324 {
325 // If this is the first doc, there is nothing to merge - just use operator=
326 *destPidf = *srcPidf;
327 }
328 else
329 {
330 destPidf->merge(*srcPidf);
331 }
332 return true;
333 }
334 return false;
335}
336
337// Used to get registrationChanged to run in DumThread context
339{
340public:
341 PresenceServerRegStateChangeCommand(PresenceSubscriptionHandler& handler, const resip::Uri& aor, bool registered, uint64_t regMaxExpires)
342 : mHandler(handler), mAor(aor), mRegistered(registered), mRegMaxExpires(regMaxExpires) {}
343
344 virtual void executeCommand()
345 {
346 mHandler.checkRegistrationStateChanged(mAor, mRegistered, mRegMaxExpires);
347 }
348
349 virtual EncodeStream& encodeBrief(EncodeStream& strm) const
350 {
351 return strm << "PresenceServerRegStateChangeCommand: aor=" << mAor << ", registered=" << mRegistered;
352 }
353private:
355 resip::Uri mAor;
356 bool mRegistered;
357 uint64_t mRegMaxExpires;
358};
359
360// Used to fabricate a presence update to all applicable subscriptions
362{
363public:
365 mHandler(handler), mAor(aor), mOnline(online), mRegMaxExpires(regMaxExpires) {}
367
369 {
370 if (mOnline)
371 {
372 if (!mHandler.sendPublishedPresence(h, false /* sendAcceptReject */))
373 {
374 // Fabricate a simple presence update based on registration state
375 mHandler.fabricateSimplePresence(h, false /* sendAcceptReject */, mAor, true /* online? */, mRegMaxExpires);
376 }
377 }
378 else
379 {
380 mHandler.fabricateSimplePresence(h, false /* sendAcceptReject */, mAor, false /* online? */, mRegMaxExpires);
381 }
382 }
383private:
385 Uri mAor;
386 bool mOnline;
387 uint64_t mRegMaxExpires;
388};
389
390bool
392{
393 // Last reported online?
394 bool online = mOnlineAors.find(aor) != mOnlineAors.end();
395 bool stateChanged = false;
396 // Check if state has changed or not
397 if (online && !registered)
398 {
399 stateChanged = true;
400 mOnlineAors.erase(aor);
401 online = false;
402 DebugLog(<< "PresenceSubscriptionHandler::checkRegistrationStateChanged: registration changed for aor=" << aor << ", no longer registered");
403 }
404 else if (!online && registered)
405 {
406 stateChanged = true;
407 mOnlineAors.insert(aor);
408 online = true;
409 DebugLog(<< "PresenceSubscriptionHandler::checkRegistrationStateChanged: registration changed for aor=" << aor << ", now registered");
410 }
411 if (stateChanged)
412 {
413 PresenceServerSubscriptionRegFunctor functor(*this, aor, online, regMaxExpires);
414 Data aorData = aor.user() + "@" + aor.host();
416 }
417 else
418 {
419 DebugLog(<< "PresenceSubscriptionHandler::checkRegistrationStateChanged: registration state unchanged for aor=" << aor);
420 }
421 return stateChanged;
422}
423
424void
426{
427 bool registered = false;
428 uint64_t maxExpirationTime = 0;
430
431 // iterate contacts and see if registered or not
432 ContactList::const_iterator it = contacts.begin();
433 for (; it != contacts.end(); it++)
434 {
435 if (it->mRegExpires > now)
436 {
437 registered = true;
438 maxExpirationTime = resipMax(maxExpirationTime, it->mRegExpires);
439 }
440 }
441
442 DebugLog(<< "PresenceSubscriptionHandler::onAorModified: registration updated aor=" << aor << ", registered=" << registered);
443
444 // Need to move the remaining processing to the DUM thread
445 mDum.post(new PresenceServerRegStateChangeCommand(*this, aor, registered, maxExpirationTime));
446}
447
448// Used to notify presence update to all applicable subscriptions
450{
451public:
454
456 {
457 mHandler.notifyPresence(h, false /* sendAcceptReject? */);
458 }
459private:
461};
462
463// Used to send notifies in DumThread context
465{
466public:
468 : mHandler(handler), mDocumentKey(documentKey) {}
469
470 virtual void executeCommand()
471 {
472 mHandler.notifySubscriptions(mDocumentKey);
473 }
474
475 virtual EncodeStream& encodeBrief(EncodeStream& strm) const
476 {
477 return strm << "PresenceServerDocStateChangeCommand: aor=" << mDocumentKey;
478 }
479private:
481 resip::Data mDocumentKey;
482};
483
484// Used to generate a timer expirey in DumThread context
486{
487public:
489 : mHandler(handler), mDocumentKey(documentKey), mETag(eTag), mLastUpdated(lastUpdated) {}
490
491 virtual void executeCommand()
492 {
493 mHandler.checkExpired(mDocumentKey, mETag, mLastUpdated);
494 }
495
496 virtual EncodeStream& encodeBrief(EncodeStream& strm) const
497 {
498 return strm << "PresenceServerCheckDocExpiredCommand: aor=" << mDocumentKey;
499 }
500private:
502 resip::Data mDocumentKey;
503 resip::Data mETag;
504 uint64_t mLastUpdated;
505};
506
507void
513
514void PresenceSubscriptionHandler::checkExpired(const resip::Data& documentKey, const resip::Data& eTag, uint64_t lastUpdated)
515{
516 //DebugLog(<< "PresenceSubscriptionHandler::checkExpired: docKey=" << documentKey << ", tag=" << eTag << ", lastUpdated=" << lastUpdated);
517 mPublicationDb->checkExpired(Symbols::Presence, documentKey, eTag, lastUpdated);
518}
519
520void
521PresenceSubscriptionHandler::onDocumentModified(bool sync, const Data& eventType, const Data& documentKey, const Data& eTag, uint64_t expirationTime, uint64_t lastUpdated, const Contents* contents, const SecurityAttributes* securityAttributes)
522{
523 if (eventType == Symbols::Presence)
524 {
525 if (contents != 0) // If contents is 0, we have a pub refresh and we don't need to send notifies out)
526 {
527 DebugLog(<< "PresenceSubscriptionHandler::onDocumentModified: aor=" << documentKey << ", eTag=" << eTag);
528 // Signal DUM thread to send notifies for this change
529 mDum.post(new PresenceServerDocStateChangeCommand(*this, documentKey));
530 }
531 // If this is a sync'd publication then set a timer to see when it times out - this is needed if sync is broken when expirey happens
532 // when timer expires then see if document has expired and if so then generate mHandler.notifySubscriptions(mDocumentKey);
533 if (sync)
534 {
535 uint64_t expiresSeconds = expirationTime - Timer::getTimeSecs();
536 if (expiresSeconds > 0)
537 {
538 //DebugLog(<< "PresenceSubscriptionHandler::onDocumentModified: starting check expired timer for sync'd publication, docKey=" << documentKey << ", tag=" << eTag << ", lastUpdated=" << lastUpdated << ", timerExpirey=" << expiresSeconds);
539 mDum.getSipStack().post(std::unique_ptr<resip::ApplicationMessage>(new PresenceServerCheckDocExpiredCommand(*this, documentKey, eTag, lastUpdated)), (unsigned int)expiresSeconds, &mDum);
540 }
541 }
542 }
543}
544
545void
546PresenceSubscriptionHandler::onDocumentRemoved(bool sync, const Data& eventType, const Data& documentKey, const Data& eTag, uint64_t lastUpdated)
547{
548 if (eventType == Symbols::Presence)
549 {
550 DebugLog(<< "PresenceSubscriptionHandler::onDocumentRemoved: aor=" << documentKey << ", eTag=" << eTag);
551 // Signal DUM thread to send notifies for this change
552 mDum.post(new PresenceServerDocStateChangeCommand(*this, documentKey));
553 }
554}
555
556/* ====================================================================
557*
558* Copyright (c) 2015-2021 SIP Spectrum, Inc. All rights reserved.
559*
560* Redistribution and use in source and binary forms, with or without
561* modification, are permitted provided that the following conditions
562* are met:
563*
564* 1. Redistributions of source code must retain the above copyright
565* notice, this list of conditions and the following disclaimer.
566*
567* 2. Redistributions in binary form must reproduce the above copyright
568* notice, this list of conditions and the following disclaimer in
569* the documentation and/or other materials provided with the
570* distribution.
571*
572* 3. Neither the name of the author(s) nor the names of any contributors
573* may be used to endorse or promote products derived from this software
574* without specific prior written permission.
575*
576* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND
577* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
578* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
579* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
580* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
581* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
582* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
583* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
584* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
585* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
586* SUCH DAMAGE.
587*
588* ====================================================================
589*
590*/
591/*
592* vi: set shiftwidth=3 expandtab:
593*/
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define ErrLog(args_)
Definition Logger.hxx:137
const uint32_t ReSubGraceTime
#define resip_assert(x)
This file needs to work for both C and C++ code.
PresenceServerCheckDocExpiredCommand(PresenceSubscriptionHandler &handler, const resip::Data &documentKey, const resip::Data &eTag, uint64_t lastUpdated)
virtual EncodeStream & encodeBrief(EncodeStream &strm) const
output a brief description to stream
PresenceServerDocStateChangeCommand(PresenceSubscriptionHandler &handler, const resip::Data &documentKey)
virtual EncodeStream & encodeBrief(EncodeStream &strm) const
output a brief description to stream
virtual EncodeStream & encodeBrief(EncodeStream &strm) const
output a brief description to stream
PresenceServerRegStateChangeCommand(PresenceSubscriptionHandler &handler, const resip::Uri &aor, bool registered, uint64_t regMaxExpires)
PresenceServerSubscriptionFunctor(PresenceSubscriptionHandler &handler)
virtual void operator()(ServerSubscriptionHandle h)
virtual void operator()(ServerSubscriptionHandle h)
PresenceServerSubscriptionRegFunctor(PresenceSubscriptionHandler &handler, const resip::Uri &aor, bool online, uint64_t regMaxExpires)
virtual bool mergeETag(resip::Contents *eTagDest, resip::Contents *eTagSrc, bool isFirst)
bool checkRegistrationStateChanged(const resip::Uri &aor, bool registered, uint64_t regMaxExpires)
void adjustNotifyExpiresTime(resip::SipMessage &notify, uint64_t regMaxExpires)
virtual void onError(resip::ServerSubscriptionHandle, const resip::SipMessage &msg)
virtual void onNewSubscription(resip::ServerSubscriptionHandle h, const resip::SipMessage &sub)
bool sendPublishedPresence(resip::ServerSubscriptionHandle h, bool sendAcceptReject)
void notifySubscriptions(const resip::Data &documentKey)
virtual void onDocumentRemoved(bool sync, const resip::Data &eventType, const resip::Data &documentKey, const resip::Data &eTag, uint64_t lastUpdated)
void fabricateSimplePresence(resip::ServerSubscriptionHandle h, bool sendAcceptReject, const resip::Uri &aor, bool online, uint64_t regMaxExpires)
void checkExpired(const resip::Data &documentKey, const resip::Data &eTag, uint64_t lastUpdated)
void continueNotifyPresenceAfterUserExistsCheck(resip::ServerSubscriptionHandle h, bool sendAcceptReject, const resip::Uri &aor, bool userExists)
virtual void onDocumentModified(bool sync, const resip::Data &eventType, const resip::Data &documentKey, const resip::Data &eTag, uint64_t expirationTime, uint64_t lastUpdated, const resip::Contents *contents, const resip::SecurityAttributes *securityAttributes)
virtual void onPublished(resip::ServerSubscriptionHandle associated, resip::ServerPublicationHandle publication, const resip::Contents *contents, const resip::SecurityAttributes *attrs)
virtual void onTerminated(resip::ServerSubscriptionHandle)
void notifyPresenceNoPublication(resip::ServerSubscriptionHandle h, bool sendAcceptReject, const resip::Uri &aor, bool isRegistered, uint64_t regMaxExpires)
PresenceSubscriptionHandler(resip::DialogUsageManager &dum, resip::Dispatcher *userDispatcher, bool presenceUsesRegistrationState, bool PresenceNotifyClosedStateForNonPublishedUsers)
void notifyPresence(resip::ServerSubscriptionHandle h, bool sendAcceptReject)
virtual void onRefresh(resip::ServerSubscriptionHandle, const resip::SipMessage &sub)
virtual void onAorModified(const resip::Uri &aor, const resip::ContactList &contacts)
The abstract base-class for all exceptions thrown by resip code.
const Data & getEventType() const noexcept
const Data & getDocumentKey() const noexcept
Base class for all SIP body types.
Definition Contents.hxx:51
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
UnaryFunction applyToServerSubscriptions(const Data &aor, const Data &eventType, UnaryFunction &applyFn)
A generic thread-bank class.
virtual bool post(std::unique_ptr< resip::ApplicationMessage > &work)
Posts a message to this thread bank.
SIP body type for holding PIDF contents (MIME content-type application/pidf+xml).
void setSimplePresenceTupleNode(const Data &id, bool online, const Data &timestamp=Data::Empty, const Data &note=Data::Empty, const Data &contact=Data::Empty, const Data &contactPriority=Data::Empty)
void setEntity(const Uri &entity)
bool merge(const GenericPidfContents &other)
bool isValid() const
Definition Handle.hxx:25
Implementation of a persistence manager.
virtual bool checkExpired(const Data &eventType, const Data &documentKey, const Data &eTag, uint64_t lastUpdated)
virtual void addHandler(InMemorySyncPubDbHandler *handler)
virtual void removeHandler(InMemorySyncPubDbHandler *handler)
virtual bool getMergedETags(const Data &eventType, const Data &documentKey, ETagMerger &merger, Contents *destination)
Implementation of a persistence manager.
virtual void addHandler(InMemorySyncRegDbHandler *handler)
virtual bool aorIsRegistered(const Uri &aor)
virtual void removeHandler(InMemorySyncRegDbHandler *handler)
std::shared_ptr< SipMessage > neutralNotify()
void setSubscriptionState(SubscriptionState state)
void end(TerminateReason reason, const Contents *document=0, int retryAfter=0)
std::shared_ptr< SipMessage > update(const Contents *document)
std::shared_ptr< SipMessage > accept(int statusCode=202)
void send(std::shared_ptr< SipMessage > msg) override
std::shared_ptr< SipMessage > reject(int responseCode)
Represents a SIP message.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
void post(std::unique_ptr< ApplicationMessage > message, unsigned int secondsLater, TransactionUser *tu=0)
Makes the message available to the TU at some later time, specified in seconds.
static const char * Presence
Definition Symbols.hxx:103
static uint64_t getTimeSecs()
Returns the current clock time in seconds.
Definition Timer.hxx:78
void post(Message *msg)
Posts a Message to this TransactionUser's fifo.
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
Data & user()
Definition Uri.hxx:42
Data & host()
Definition Uri.hxx:40
This Class is used to implement a primitive form of RPC using loose XML formatting.
dcm! – add UnusedChecking(_enum) below;
const _Tp & resipMin(const _Tp &__a, const _Tp &__b)
Definition compat.hxx:182
const _Tp & resipMax(const _Tp &__a, const _Tp &__b)
Definition compat.hxx:194
std::list< ContactInstanceRecord > ContactList
#define EncodeStream
unsigned int uint32_t
Definition stdint.h:85
unsigned __int64 uint64_t
Definition stdint.h:95