|
reSIProcate/DialogUsageManager
9694
|
dcm! -- shutdown/deletion API -- end? More...
#include <ClientRegistration.hxx>


Public Member Functions | |
| ClientRegistration (DialogUsageManager &dum, DialogSet &dialog, SharedPtr< SipMessage > req) | |
| ClientRegistrationHandle | getHandle () |
| void | addBinding (const NameAddr &contact) |
| Adds a registration binding, using the registration from the UserProfile. | |
| void | addBinding (const NameAddr &contact, UInt32 registrationTime) |
| Adds a registration binding, using the specified registration time. | |
| void | removeBinding (const NameAddr &contact) |
| Removes one particular binding. | |
| void | removeAll (bool stopRegisteringWhenDone=false) |
| Removes all bindings associated with the AOR - even those that may have been by a another UA. | |
| void | removeMyBindings (bool stopRegisteringWhenDone=false) |
| Removes all bindings added by addBinding. | |
| void | requestRefresh (UInt32 expires=0) |
| Request a manual refresh of the registration. | |
| void | stopRegistering () |
| kills the usgage, does not unregister, call removeMyBindings to unregister | |
| const NameAddrs & | myContacts () |
| returns a list of contacts added by addBinding | |
| const NameAddrs & | allContacts () |
| returns a list of all contacts for this AOR - may include those added by other UA's | |
| UInt32 | whenExpires () const |
| returns the number of seconds until the registration expires - relative | |
| virtual void | end () |
| Calls removeMyBindings and ends usage when complete. | |
| void | removeMyBindingsCommand (bool stopRegisteringWhenDone=false) |
| Provide asynchronous method access by using command. | |
| virtual void | endCommand () |
| virtual void | dispatch (const SipMessage &msg) |
| virtual void | dispatch (const DumTimeout &timer) |
| virtual EncodeStream & | dump (EncodeStream &strm) const |
Static Public Member Functions | |
| static void | tagContact (NameAddr &contact, DialogUsageManager &dum, SharedPtr< UserProfile > &userProfile) |
Protected Member Functions | |
| virtual | ~ClientRegistration () |
Private Types | |
| enum | State { Querying, Adding, Refreshing, Registered, Removing, RetryAdding, RetryRefreshing, None } |
Private Member Functions | |
| SharedPtr< SipMessage > | tryModification (ClientRegistration::State state) |
| void | internalRequestRefresh (UInt32 expires=0) |
| unsigned int | checkProfileRetry (const SipMessage &msg) |
| void | tagContact (NameAddr &contact) const |
| unsigned long | calculateExpiry (const SipMessage ®200) const |
| bool | contactIsMine (const NameAddr &contact) const |
| bool | rinstanceIsMine (const Data &rinstance) const |
| bool | searchByUri (const Uri &cUri) const |
| void | flowTerminated () |
| ClientRegistration (const ClientRegistration &) | |
| ClientRegistration & | operator= (const ClientRegistration &) |
Private Attributes | |
| SharedPtr< SipMessage > | mLastRequest |
| NameAddrs | mMyContacts |
| NameAddrs | mAllContacts |
| unsigned int | mTimerSeq |
| State | mState |
| bool | mEndWhenDone |
| bool | mUserRefresh |
| UInt32 | mRegistrationTime |
| UInt64 | mExpires |
| State | mQueuedState |
| SharedPtr< SipMessage > | mQueuedRequest |
| NetworkAssociation | mNetworkAssociation |
Friends | |
| class | DialogSet |
dcm! -- shutdown/deletion API -- end?
Definition at line 16 of file ClientRegistration.hxx.
enum resip::ClientRegistration::State [private] |
Definition at line 80 of file ClientRegistration.hxx.
{
Querying,
Adding,
Refreshing,
Registered,
Removing,
RetryAdding, // Waiting to retry an add
RetryRefreshing, // Waiting to retry a refresh
None // for queued only
} State;
| ClientRegistration::ClientRegistration | ( | DialogUsageManager & | dum, |
| DialogSet & | dialog, | ||
| SharedPtr< SipMessage > | req | ||
| ) |
Definition at line 29 of file ClientRegistration.cxx.
References mLastRequest, mMyContacts, mNetworkAssociation, mRegistrationTime, None, and resip::NetworkAssociation::setDum().
: NonDialogUsage(dum, dialogSet), mLastRequest(request), mTimerSeq(0), mState(mLastRequest->exists(h_Contacts) ? Adding : Querying), mEndWhenDone(false), mUserRefresh(false), mRegistrationTime(mDialogSet.mUserProfile->getDefaultRegistrationTime()), mExpires(0), mQueuedState(None), mQueuedRequest(new SipMessage) { // If no Contacts header, this is a query if (mLastRequest->exists(h_Contacts)) { mMyContacts = mLastRequest->header(h_Contacts); } if(mLastRequest->exists(h_Expires) && mLastRequest->header(h_Expires).isWellFormed()) { mRegistrationTime = mLastRequest->header(h_Expires).value(); } mNetworkAssociation.setDum(&dum); }

| ClientRegistration::~ClientRegistration | ( | ) | [protected, virtual] |
Definition at line 58 of file ClientRegistration.cxx.
References DebugLog, resip::DialogSet::mClientRegistration, resip::NonDialogUsage::mDialogSet, and resip::DialogSet::mUserProfile.
{
DebugLog ( << "ClientRegistration::~ClientRegistration" );
mDialogSet.mClientRegistration = 0;
// !dcm! Will not interact well with multiple registrations from the same AOR
mDialogSet.mUserProfile->setServiceRoute(NameAddrs());
}
| resip::ClientRegistration::ClientRegistration | ( | const ClientRegistration & | ) | [private] |
| void ClientRegistration::addBinding | ( | const NameAddr & | contact | ) |
Adds a registration binding, using the registration from the UserProfile.
Definition at line 68 of file ClientRegistration.cxx.
References resip::NonDialogUsage::mDialogSet, and resip::DialogSet::mUserProfile.
{
addBinding(contact, mDialogSet.mUserProfile->getDefaultRegistrationTime());
}
Adds a registration binding, using the specified registration time.
Definition at line 104 of file ClientRegistration.cxx.
References Adding, resip::ParserContainer< T >::back(), mMyContacts, mQueuedState, mRegistrationTime, None, resip::ParserContainer< T >::push_back(), resip::NonDialogUsage::send(), tagContact(), and tryModification().
{
SharedPtr<SipMessage> next = tryModification(Adding);
mMyContacts.push_back(contact);
tagContact(mMyContacts.back());
next->header(h_Contacts) = mMyContacts;
mRegistrationTime = registrationTime;
next->header(h_Expires).value() = mRegistrationTime;
next->header(h_CSeq).sequence()++;
// caller prefs
if (mQueuedState == None)
{
send(next);
}
}

| const NameAddrs & ClientRegistration::allContacts | ( | ) |
returns a list of all contacts for this AOR - may include those added by other UA's
Definition at line 303 of file ClientRegistration.cxx.
References mAllContacts.
{
return mAllContacts;
}
| unsigned long ClientRegistration::calculateExpiry | ( | const SipMessage & | reg200 | ) | const [private] |
Definition at line 751 of file ClientRegistration.cxx.
References contactIsMine(), resip::SipMessage::exists(), resip::SipMessage::header(), resip::LazyParser::isWellFormed(), and mRegistrationTime.
Referenced by dispatch().
{
unsigned long expiry=mRegistrationTime;
if(reg200.exists(h_Expires) &&
reg200.header(h_Expires).isWellFormed() &&
reg200.header(h_Expires).value() < expiry)
{
expiry=reg200.header(h_Expires).value();
}
if(!reg200.exists(h_Contacts))
{
return expiry;
}
const NameAddrs& contacts(reg200.header(h_Contacts));
for(NameAddrs::const_iterator c=contacts.begin();c!=contacts.end();++c)
{
// Our expiry is never going to increase if we find one of our contacts,
// so if the expiry is not lower, we just ignore it. For registrars that
// leave our requested expiry alone, this code ends up being pretty quick,
// especially if there aren't contacts from other endpoints laying around.
if(c->isWellFormed() &&
c->exists(p_expires) &&
c->param(p_expires) < expiry &&
contactIsMine(*c))
{
expiry=c->param(p_expires);
}
}
return expiry;
}

| unsigned int ClientRegistration::checkProfileRetry | ( | const SipMessage & | msg | ) | [private] |
Definition at line 842 of file ClientRegistration.cxx.
References Adding, resip::DialogUsageManager::addTimer(), resip::SipMessage::exists(), resip::BaseUsage::getBaseHandle(), resip::SipMessage::header(), resip::DialogUsageManager::mClientAuthManager, resip::NonDialogUsage::mDialogSet, resip::BaseUsage::mDum, mEndWhenDone, mExpires, mLastRequest, mState, mTimerSeq, resip::DialogSet::mUserProfile, Refreshing, resip::DumTimeout::RegistrationRetry, RetryAdding, and RetryRefreshing.
Referenced by dispatch().
{
unsigned int retryInterval = mDialogSet.mUserProfile->getDefaultRegistrationRetryTime();
if (retryInterval > 0 &&
(mState == Adding || mState == Refreshing) &&
!mEndWhenDone)
{
if (msg.exists(h_RetryAfter) && msg.header(h_RetryAfter).value() > 0)
{
// Use retry interval from error response
retryInterval = msg.header(h_RetryAfter).value();
}
mExpires = 0;
switch(mState)
{
case Adding:
mState = RetryAdding;
break;
case Refreshing:
mState = RetryRefreshing;
break;
default:
assert(false);
break;
}
if(mDum.mClientAuthManager.get()) mDum.mClientAuthManager.get()->clearAuthenticationState(DialogSetId(*mLastRequest));
mDum.addTimer(DumTimeout::RegistrationRetry,
retryInterval,
getBaseHandle(),
++mTimerSeq);
return retryInterval;
}
return 0;
}

| bool ClientRegistration::contactIsMine | ( | const NameAddr & | contact | ) | const [private] |
Definition at line 786 of file ClientRegistration.cxx.
References resip::NameAddr::exists(), resip::Uri::exists(), resip::NonDialogUsage::mDialogSet, resip::DialogSet::mUserProfile, resip::ParserCategory::param(), rinstanceIsMine(), searchByUri(), and resip::NameAddr::uri().
Referenced by calculateExpiry().
{
// Try to find this contact in mMyContacts
if(mDialogSet.mUserProfile->hasInstanceId() &&
contact.exists(p_Instance))
{
return contact.param(p_Instance)==mDialogSet.mUserProfile->getInstanceId();
}
else if(mDialogSet.mUserProfile->getRinstanceEnabled() &&
contact.uri().exists(p_rinstance))
{
return rinstanceIsMine(contact.uri().param(p_rinstance));
}
else
{
return searchByUri(contact.uri());
}
}

| void ClientRegistration::dispatch | ( | const SipMessage & | msg | ) | [virtual] |
Implements resip::BaseUsage.
Definition at line 359 of file ClientRegistration.cxx.
References resip::Helper::aBitSmallerThan(), Adding, resip::DialogUsageManager::addTimer(), calculateExpiry(), checkProfileRetry(), resip::ParserContainerBase::clear(), DebugLog, resip::SipMessage::empty(), end(), ErrLog, resip::SipMessage::exists(), resip::Uri::exists(), resip::BaseUsage::getBaseHandle(), getHandle(), resip::BaseException::getMessage(), resip::SipMessage::getReceivedTransport(), resip::SipMessage::getSource(), resip::Timer::getTimeSecs(), resip::NonDialogUsage::getUserProfile(), h_StatusLine, resip::SipMessage::header(), InfoLog, resip::Inserter(), resip::SipMessage::isExternal(), resip::SipMessage::isResponse(), mAllContacts, resip::DialogUsageManager::mClientAuthManager, resip::DialogUsageManager::mClientRegistrationHandler, resip::NonDialogUsage::mDialogSet, resip::BaseUsage::mDum, mEndWhenDone, mExpires, mLastRequest, mNetworkAssociation, mQueuedRequest, mQueuedState, mRegistrationTime, mState, mTimerSeq, resip::DialogSet::mUserProfile, mUserRefresh, None, resip::ClientRegistrationHandler::onFailure(), resip::ClientRegistrationHandler::onRemoved(), resip::ClientRegistrationHandler::onRequestRetry(), resip::ClientRegistrationHandler::onSuccess(), resip::Symbols::Outbound, Querying, Refreshing, Registered, resip::DumTimeout::Registration, resip::DumTimeout::RegistrationRetry, Removing, RetryAdding, RetryRefreshing, resip::Symbols::SCTP, resip::NonDialogUsage::send(), stopRegistering(), resip::Symbols::TCP, resip::Symbols::TLS, resip::NetworkAssociation::update(), resip::RequestLine::uri(), and WarningLog.
Referenced by resip::DialogSet::dispatch().
{
try
{
// !jf! there may be repairable errors that we can handle here
assert(msg.isResponse());
const int& code = msg.header(h_StatusLine).statusCode();
bool nextHopSupportsOutbound = false;
int keepAliveTime = 0;
// If registration was successful - look for next hop indicating support for outbound
if(mDialogSet.mUserProfile->clientOutboundEnabled() && msg.isExternal() && code >= 200 && code < 300)
{
// If ClientOutbound support is enabled and the registration response contains
// Requires: outbound or a Path with outbound then outbound is supported by the
// server, so store the flow key in the UserProfile
// and use it for sending all messages (DialogUsageManager::sendUsingOutboundIfAppropriate)
try
{
if((!msg.empty(h_Paths) && msg.header(h_Paths).back().uri().exists(p_ob)) ||
(!msg.empty(h_Requires) && msg.header(h_Requires).find(Token(Symbols::Outbound))))
{
mDialogSet.mUserProfile->mClientOutboundFlowTuple = msg.getSource();
mDialogSet.mUserProfile->mClientOutboundFlowTuple.onlyUseExistingConnection = true;
nextHopSupportsOutbound = true;
if(!msg.empty(h_FlowTimer))
{
keepAliveTime = msg.header(h_FlowTimer).value();
}
}
}
catch(BaseException&e)
{
ErrLog(<<"Error parsing Path or Requires:" << e);
}
}
if(msg.isExternal())
{
const Data& receivedTransport = msg.header(h_Vias).front().transport();
if(keepAliveTime == 0)
{
if(receivedTransport == Symbols::TCP ||
receivedTransport == Symbols::TLS ||
receivedTransport == Symbols::SCTP)
{
keepAliveTime = mDialogSet.mUserProfile->getKeepAliveTimeForStream();
}
else
{
keepAliveTime = mDialogSet.mUserProfile->getKeepAliveTimeForDatagram();
}
}
if(keepAliveTime > 0)
{
mNetworkAssociation.update(msg, keepAliveTime, nextHopSupportsOutbound);
}
}
if (code < 200)
{
// throw it away
return;
}
else if (code < 300) // success
{
try
{
if (msg.exists(h_ServiceRoutes))
{
InfoLog(<< "Updating service route: " << Inserter(msg.header(h_ServiceRoutes)));
mDialogSet.mUserProfile->setServiceRoute(msg.header(h_ServiceRoutes));
}
else
{
DebugLog(<< "Clearing service route (" << Inserter(getUserProfile()->getServiceRoute()) << ")");
mDialogSet.mUserProfile->setServiceRoute(NameAddrs());
}
}
catch(BaseException &e)
{
ErrLog(<< "Error Parsing Service Route:" << e);
}
//gruu update, should be optimized
try
{
if(mDialogSet.mUserProfile->gruuEnabled() && msg.exists(h_Contacts))
{
for (NameAddrs::const_iterator it = msg.header(h_Contacts).begin();
it != msg.header(h_Contacts).end(); it++)
{
if (it->exists(p_Instance) && it->param(p_Instance) == mDialogSet.mUserProfile->getInstanceId())
{
if(it->exists(p_pubGruu))
{
mDialogSet.mUserProfile->setPublicGruu(Uri(it->param(p_pubGruu)));
}
if(it->exists(p_tempGruu))
{
mDialogSet.mUserProfile->setTempGruu(Uri(it->param(p_tempGruu)));
}
break;
}
}
}
}
catch(BaseException&e)
{
ErrLog(<<"Error parsing GRUU:" << e);
}
// !jf! consider what to do if no contacts
// !ah! take list of ctcs and push into mMy or mOther as required.
// make timers to re-register
UInt32 expiry = calculateExpiry(msg);
if(msg.exists(h_Contacts))
{
mAllContacts = msg.header(h_Contacts);
}
else
{
mAllContacts.clear();
}
if (expiry != 0 && expiry != UINT_MAX)
{
if(expiry>=7)
{
int exp = Helper::aBitSmallerThan(expiry);
mExpires = exp + Timer::getTimeSecs();
mDum.addTimer(DumTimeout::Registration,
exp,
getBaseHandle(),
++mTimerSeq);
}
else
{
WarningLog(<< "Server is using an unreasonably low expiry: "
<< expiry
<< " We're just going to end this registration.");
end();
return;
}
}
switch (mState)
{
case Querying:
case Adding:
if(expiry != 0)
{
mState = Registered;
mDum.mClientRegistrationHandler->onSuccess(getHandle(), msg);
}
else
{
mDum.mClientRegistrationHandler->onRemoved(getHandle(), msg);
checkProfileRetry(msg);
}
break;
case Removing:
//mDum.mClientRegistrationHandler->onSuccess(getHandle(), msg);
mDum.mClientRegistrationHandler->onRemoved(getHandle(), msg);
InfoLog (<< "Finished removing registration " << *this << " mEndWhenDone=" << mEndWhenDone);
if (mEndWhenDone)
{
// !kh!
// stopRegistering() deletes 'this'
// furthur processing makes no sense
//assert(mQueuedState == None);
stopRegistering();
return;
}
break;
case Registered:
case Refreshing:
mState = Registered;
if(expiry != 0)
{
if(mUserRefresh)
{
mUserRefresh = false;
mDum.mClientRegistrationHandler->onSuccess(getHandle(), msg);
}
}
else
{
mDum.mClientRegistrationHandler->onRemoved(getHandle(), msg);
checkProfileRetry(msg);
}
break;
default:
break;
}
if (mQueuedState != None)
{
InfoLog (<< "Sending queued request: " << *mQueuedRequest);
mState = mQueuedState;
mQueuedState = None;
*mLastRequest = *mQueuedRequest;
send(mLastRequest);
}
}
else
{
if((mState == Adding || mState == Refreshing) && !mEndWhenDone)
{
if (code == 423) // interval too short
{
UInt32 maxRegistrationTime = mDialogSet.mUserProfile->getDefaultMaxRegistrationTime();
if (msg.exists(h_MinExpires) &&
(maxRegistrationTime == 0 || msg.header(h_MinExpires).value() < maxRegistrationTime)) // If maxRegistrationTime is enabled, then check it
{
mRegistrationTime = msg.header(h_MinExpires).value();
mLastRequest->header(h_Expires).value() = mRegistrationTime;
mLastRequest->header(h_CSeq).sequence()++;
send(mLastRequest);
return;
}
}
else if (code == 408 || (code == 503 && msg.getReceivedTransport() == 0))
{
int retry = mDum.mClientRegistrationHandler->onRequestRetry(getHandle(), 0, msg);
if (retry < 0)
{
DebugLog(<< "Application requested failure on Retry-After");
}
else if (retry == 0)
{
DebugLog(<< "Application requested immediate retry on 408 or internal 503");
mLastRequest->header(h_CSeq).sequence()++;
send(mLastRequest);
mUserRefresh = true; // Reset this flag, so that the onSuccess callback will be called if we are successful when re-trying
return;
}
else
{
DebugLog(<< "Application requested delayed retry on 408 or internal 503: " << retry);
mExpires = 0;
switch(mState)
{
case Adding:
mState = RetryAdding;
break;
case Refreshing:
mState = RetryRefreshing;
break;
default:
assert(false);
break;
}
if(mDum.mClientAuthManager.get()) mDum.mClientAuthManager.get()->clearAuthenticationState(DialogSetId(*mLastRequest));
mDum.addTimer(DumTimeout::RegistrationRetry,
retry,
getBaseHandle(),
++mTimerSeq);
mUserRefresh = true; // Reset this flag, so that the onSuccess callback will be called if we are successful when re-trying
return;
}
}
}
mDum.mClientRegistrationHandler->onFailure(getHandle(), msg);
mUserRefresh = true; // Reset this flag, so that the onSuccess callback will be called if we are successful when re-trying
// Retry if Profile setting is set
unsigned int retryInterval = checkProfileRetry(msg);
if(retryInterval > 0)
{
InfoLog( << "Registration error " << code << " for " << msg.header(h_To) << ", retrying in " << retryInterval << " seconds.");
return;
}
// assume that if a failure occurred, the bindings are gone
if (mEndWhenDone)
{
mDum.mClientRegistrationHandler->onRemoved(getHandle(), msg);
}
delete this;
}
}
catch(BaseException& e)
{
InfoLog( << "Exception in ClientRegistration::dispatch: " << e.getMessage());
mDum.mClientRegistrationHandler->onFailure(getHandle(), msg);
delete this;
}
}

| void ClientRegistration::dispatch | ( | const DumTimeout & | timer | ) | [virtual] |
Implements resip::BaseUsage.
Definition at line 879 of file ClientRegistration.cxx.
References Adding, resip::ParserContainerBase::empty(), internalRequestRefresh(), mLastRequest, mMyContacts, mState, mTimerSeq, Refreshing, Registered, resip::DumTimeout::Registration, resip::DumTimeout::RegistrationRetry, RetryAdding, RetryRefreshing, resip::NonDialogUsage::send(), resip::DumTimeout::seq(), and resip::DumTimeout::type().
{
switch(timer.type())
{
case DumTimeout::Registration:
// If you happen to be Adding/Updating when the timer goes off, you should just ignore
// it since a new timer will get added when the 2xx is received.
if (timer.seq() == mTimerSeq && mState == Registered)
{
if (!mMyContacts.empty())
{
internalRequestRefresh();
}
}
break;
case DumTimeout::RegistrationRetry:
if (timer.seq() == mTimerSeq)
{
switch(mState)
{
case RetryAdding:
mState = Adding;
break;
case RetryRefreshing:
mState = Refreshing;
break;
default:
assert(false);
break;
}
// Resend last request
mLastRequest->header(h_CSeq).sequence()++;
mLastRequest->remove(h_ProxyAuthorizations);
mLastRequest->remove(h_Authorizations);
send(mLastRequest);
}
break;
default:
break;
}
}

| EncodeStream & ClientRegistration::dump | ( | EncodeStream & | strm | ) | const [virtual] |
Implements resip::BaseUsage.
Definition at line 352 of file ClientRegistration.cxx.
References mLastRequest.
{
strm << "ClientRegistration " << mLastRequest->header(h_From).uri();
return strm;
}
| void ClientRegistration::end | ( | ) | [virtual] |
Calls removeMyBindings and ends usage when complete.
Implements resip::BaseUsage.
Definition at line 318 of file ClientRegistration.cxx.
References removeMyBindings().
Referenced by dispatch().
{
removeMyBindings(true);
}

| void ClientRegistration::endCommand | ( | ) | [virtual] |
Definition at line 346 of file ClientRegistration.cxx.
References resip::BaseUsage::mDum, and resip::TransactionUser::post().
{
mDum.post(new ClientRegistrationEndCommand(*this));
}

| void ClientRegistration::flowTerminated | ( | ) | [private] |
Definition at line 924 of file ClientRegistration.cxx.
References resip::NetworkAssociation::clear(), getHandle(), resip::DialogUsageManager::mClientRegistrationHandler, resip::BaseUsage::mDum, mNetworkAssociation, and resip::ClientRegistrationHandler::onFlowTerminated().
Referenced by resip::DialogSet::flowTerminated().
{
// Clear the network association
mNetworkAssociation.clear();
// Notify application - not default handler implementation is to immediately attempt
// a re-registration in order to form a new flow
mDum.mClientRegistrationHandler->onFlowTerminated(getHandle());
}

| ClientRegistrationHandle ClientRegistration::getHandle | ( | ) |
Definition at line 24 of file ClientRegistration.cxx.
References resip::BaseUsage::getBaseHandle(), and resip::BaseUsage::mDum.
Referenced by dispatch(), flowTerminated(), and resip::DialogSet::getClientRegistration().
{
return ClientRegistrationHandle(mDum, getBaseHandle().getId());
}

| void ClientRegistration::internalRequestRefresh | ( | UInt32 | expires = 0 | ) | [private] |
Definition at line 269 of file ClientRegistration.cxx.
References InfoLog, mLastRequest, mMyContacts, mRegistrationTime, mState, mTimerSeq, Refreshing, Registered, RetryAdding, RetryRefreshing, and resip::NonDialogUsage::send().
Referenced by dispatch(), and requestRefresh().
{
if(mState == RetryAdding && mState == RetryRefreshing)
{
// disable retry time and try refresh immediately
++mTimerSeq;
}
else if (mState != Registered)
{
InfoLog (<< "a request is already in progress, no need to refresh " << *this);
return;
}
InfoLog (<< "requesting refresh of " << *this);
mState = Refreshing;
mLastRequest->header(h_CSeq).sequence()++;
mLastRequest->header(h_Contacts)=mMyContacts;
if(expires > 0)
{
mRegistrationTime = expires;
}
mLastRequest->header(h_Expires).value()=mRegistrationTime;
send(mLastRequest);
}

| const NameAddrs & ClientRegistration::myContacts | ( | ) |
returns a list of contacts added by addBinding
Definition at line 297 of file ClientRegistration.cxx.
References mMyContacts.
Referenced by removeMyBindings().
{
return mMyContacts;
}
| ClientRegistration& resip::ClientRegistration::operator= | ( | const ClientRegistration & | ) | [private] |
| void ClientRegistration::removeAll | ( | bool | stopRegisteringWhenDone = false | ) |
Removes all bindings associated with the AOR - even those that may have been by a another UA.
Note: Set's contact header to '*'. Set flag to true to end the usage when complete.
Definition at line 156 of file ClientRegistration.cxx.
References resip::ParserContainerBase::clear(), mAllContacts, mEndWhenDone, mMyContacts, mQueuedState, mState, None, Removing, resip::NonDialogUsage::send(), resip::NameAddr::setAllContacts(), tryModification(), and WarningLog.
{
if (mState == Removing)
{
WarningLog (<< "Already removing a binding");
throw UsageUseException("Can't remove binding when already removing registration bindings", __FILE__,__LINE__);
}
SharedPtr<SipMessage> next = tryModification(Removing);
mAllContacts.clear();
mMyContacts.clear();
NameAddr all;
all.setAllContacts();
next->header(h_Contacts).clear();
next->header(h_Contacts).push_back(all);
next->header(h_Expires).value() = 0;
next->header(h_CSeq).sequence()++;
mEndWhenDone = stopRegisteringWhenDone;
if (mQueuedState == None)
{
send(next);
}
}

| void ClientRegistration::removeBinding | ( | const NameAddr & | contact | ) |
Removes one particular binding.
Definition at line 123 of file ClientRegistration.cxx.
References resip::ParserContainer< T >::begin(), resip::ParserContainer< T >::end(), resip::ParserContainer< T >::erase(), mMyContacts, mQueuedState, mState, None, Removing, resip::NonDialogUsage::send(), tryModification(), resip::NameAddr::uri(), and WarningLog.
{
if (mState == Removing)
{
WarningLog (<< "Already removing a binding");
throw UsageUseException("Can't remove binding when already removing registration bindings", __FILE__,__LINE__);
}
SharedPtr<SipMessage> next = tryModification(Removing);
for (NameAddrs::iterator i=mMyContacts.begin(); i != mMyContacts.end(); i++)
{
if (i->uri() == contact.uri())
{
next->header(h_Contacts).clear();
next->header(h_Contacts).push_back(*i);
next->header(h_Expires).value() = 0;
next->header(h_CSeq).sequence()++;
if (mQueuedState == None)
{
send(next);
}
mMyContacts.erase(i);
return;
}
}
// !jf! What state are we left in now?
throw Exception("No such binding", __FILE__, __LINE__);
}

| void ClientRegistration::removeMyBindings | ( | bool | stopRegisteringWhenDone = false | ) |
Removes all bindings added by addBinding.
Set flag to true to end the usage when complete
Definition at line 184 of file ClientRegistration.cxx.
References resip::ParserContainer< T >::begin(), resip::ParserContainerBase::clear(), resip::ParserContainerBase::empty(), resip::ParserContainer< T >::end(), InfoLog, mEndWhenDone, mMyContacts, mQueuedState, mState, myContacts(), None, Removing, resip::NonDialogUsage::send(), tryModification(), and WarningLog.
Referenced by end().
{
InfoLog (<< "Removing binding");
if (mState == Removing)
{
WarningLog (<< "Already removing a binding");
throw UsageUseException("Can't remove binding when already removing registration bindings", __FILE__,__LINE__);
}
if (mMyContacts.empty())
{
WarningLog (<< "No bindings to remove");
throw UsageUseException("No bindings to remove", __FILE__,__LINE__);
}
SharedPtr<SipMessage> next = tryModification(Removing);
next->header(h_Contacts) = mMyContacts;
mMyContacts.clear();
NameAddrs& myContacts = next->header(h_Contacts);
for (NameAddrs::iterator i=myContacts.begin(); i != myContacts.end(); i++)
{
i->param(p_expires) = 0;
}
next->remove(h_Expires);
next->header(h_CSeq).sequence()++;
// !jf! is this ok if queued
mEndWhenDone = stopRegisteringWhenDone;
if (mQueuedState == None)
{
send(next);
}
}

| void ClientRegistration::removeMyBindingsCommand | ( | bool | stopRegisteringWhenDone = false | ) |
Provide asynchronous method access by using command.
Definition at line 248 of file ClientRegistration.cxx.
References resip::BaseUsage::mDum, and resip::TransactionUser::post().
{
mDum.post(new ClientRegistrationRemoveMyBindings(*this, stopRegisteringWhenDone));
}

| void ClientRegistration::requestRefresh | ( | UInt32 | expires = 0 | ) |
Request a manual refresh of the registration.
If 0 then default to using original expires value (to remove use removeXXX() instead)
Definition at line 261 of file ClientRegistration.cxx.
References internalRequestRefresh(), and mUserRefresh.
{
// Set flag so that handlers get called for success/failure
mUserRefresh = true;
internalRequestRefresh(expires);
}

| bool ClientRegistration::rinstanceIsMine | ( | const Data & | rinstance | ) | const [private] |
Definition at line 806 of file ClientRegistration.cxx.
References resip::ParserContainer< T >::begin(), resip::ParserContainer< T >::end(), and mMyContacts.
Referenced by contactIsMine().
{
// !bwc! This could be made faster if we used a single rinstance...
for(NameAddrs::const_iterator m=mMyContacts.begin(); m!=mMyContacts.end(); ++m)
{
if(m->uri().exists(p_rinstance) && m->uri().param(p_rinstance)==rinstance)
{
return true;
}
}
return false;
}

| bool ClientRegistration::searchByUri | ( | const Uri & | cUri | ) | const [private] |
Definition at line 820 of file ClientRegistration.cxx.
References resip::ParserContainer< T >::begin(), resip::ParserContainer< T >::end(), resip::DialogUsageManager::getSipStack(), resip::Uri::host(), resip::SipStack::isMyDomain(), resip::BaseUsage::mDum, mMyContacts, resip::Uri::port(), resip::Uri::scheme(), and resip::Uri::user().
Referenced by contactIsMine().
{
for(NameAddrs::const_iterator m=mMyContacts.begin(); m!=mMyContacts.end(); ++m)
{
if(m->uri()==cUri)
{
return true;
}
else if(m->uri().host().empty() &&
m->uri().user()==cUri.user() &&
m->uri().scheme()==cUri.scheme() &&
mDum.getSipStack().isMyDomain(cUri.host(), cUri.port()))
{
// Empty host-part in our contact; this means we're relying on the
// stack to fill out this Contact header. Also, the user-part matches.
return true;
}
}
return false;
}

| void ClientRegistration::stopRegistering | ( | ) |
kills the usgage, does not unregister, call removeMyBindings to unregister
Definition at line 254 of file ClientRegistration.cxx.
Referenced by dispatch().
{
//timers aren't a concern, as DUM checks for Handle validity before firing.
delete this;
}
| void ClientRegistration::tagContact | ( | NameAddr & | contact, |
| DialogUsageManager & | dum, | ||
| SharedPtr< UserProfile > & | userProfile | ||
| ) | [static] |
Definition at line 664 of file ClientRegistration.cxx.
References resip::Data::empty(), ErrLog, resip::Random::getCryptoRandomHex(), resip::DialogUsageManager::getMasterProfile(), resip::DialogUsageManager::getSipStack(), resip::Uri::host(), InfoLog, resip::SipStack::isMyDomain(), resip::ParserCategory::param(), resip::Uri::port(), resip::NameAddr::uri(), resip::Uri::user(), and WarningLog.
Referenced by addBinding(), resip::RegistrationCreator::RegistrationCreator(), and tagContact().
{
if(contact.uri().host().empty() ||
dum.getSipStack().isMyDomain(contact.uri().host(), contact.uri().port()))
{
// Contact points at us; it is appropriate to add a +sip.instance to
// this Contact. We don't need to have full gruu support enabled to add
// a +sip.instance either...
if(userProfile->hasInstanceId())
{
contact.param(p_Instance) = userProfile->getInstanceId();
if(userProfile->getRegId() != 0)
{
contact.param(p_regid) = userProfile->getRegId();
}
}
else if(userProfile->getRinstanceEnabled())
{
// !slg! poor mans instance id so that we can tell which contacts
// are ours - to be replaced by gruu someday.
InfoLog(<< "You really should consider setting an instance id in"
" the UserProfile (see UserProfile::setInstanceId())."
" This is really easy, and makes this class much less "
"likely to clash with another endpoint registering at "
"the same AOR.");
contact.uri().param(p_rinstance) = Random::getCryptoRandomHex(8);
}
else if(!contact.uri().user().empty())
{
WarningLog(<< "Ok, not only have you not specified an instance id, "
"you have disabled the rinstance hack (ie; resip's \"poor"
" man's +sip.instance\"). We will try to match Contacts"
" based on what you've put in the user-part of your "
"Contact, but this can be dicey, especially if you've put"
" something there that another endpoint is likely to "
"use.");
}
else
{
ErrLog(<< "Ok, not only have you not specified an instance id, "
"you have disabled the rinstance hack (ie; resip's \"poor"
" man's +sip.instance\"), _and_ you haven't put anything"
" in the user-part of your Contact. This is asking for "
"confusion later. We'll do our best to try to match things"
" up later when the response comes in...");
}
}
else
{
// Looks like a third-party registration. +sip.instance is out of the
// question, but we can still use rinstance.
if(userProfile->getRinstanceEnabled())
{
// !slg! poor mans instance id so that we can tell which contacts
// are ours - to be replaced by gruu someday.
contact.uri().param(p_rinstance) = Random::getCryptoRandomHex(8);
}
else if(!contact.uri().user().empty())
{
WarningLog(<< "You're trying to do a third-party registration, but "
"you have disabled the rinstance hack (ie; resip's \"poor"
" man's +sip.instance\"). We will try to match Contacts"
" based on what you've put in the user-part of your "
"Contact, but this can be dicey, especially if you've put"
" something there that another endpoint is likely to "
"use.");
}
else
{
ErrLog(<< "You're trying to do a third-party registration, and "
"not only have you disabled the rinstance hack (ie; "
"resip's \"poor man's +sip.instance\"), you haven't"
" put anything in the user-part of your Contact. This is "
"asking for confusion later. We'll do our best to try to "
"match things up later when the response comes in...");
}
}
if (userProfile->getMethodsParamEnabled())
{
contact.param(p_methods) = dum.getMasterProfile()->getAllowedMethodsData();
}
// ?bwc? Host and port override?
}

| void ClientRegistration::tagContact | ( | NameAddr & | contact | ) | const [private] |
Definition at line 658 of file ClientRegistration.cxx.
References resip::NonDialogUsage::mDialogSet, resip::BaseUsage::mDum, resip::DialogSet::mUserProfile, and tagContact().
{
tagContact(contact, mDum, mDialogSet.mUserProfile);
}

| SharedPtr< SipMessage > ClientRegistration::tryModification | ( | ClientRegistration::State | state | ) | [private] |
Definition at line 74 of file ClientRegistration.cxx.
References mLastRequest, mQueuedRequest, mQueuedState, mState, mTimerSeq, None, Registered, RetryAdding, RetryRefreshing, and WarningLog.
Referenced by addBinding(), removeAll(), removeBinding(), and removeMyBindings().
{
if (mState != Registered)
{
if(mState != RetryAdding && mState != RetryRefreshing)
{
if (mQueuedState != None)
{
WarningLog (<< "Trying to modify bindings when another request is already queued");
throw UsageUseException("Queuing multiple requests for Registration Bindings", __FILE__,__LINE__);
}
*mQueuedRequest = *mLastRequest;
mQueuedState = state;
return mQueuedRequest;
}
else
{
++mTimerSeq; // disable retry timer
}
}
assert(mQueuedState == None);
mState = state;
return mLastRequest;
}
| UInt32 ClientRegistration::whenExpires | ( | ) | const |
returns the number of seconds until the registration expires - relative
Definition at line 309 of file ClientRegistration.cxx.
References resip::Timer::getTimeSecs(), and mExpires.
{
// !cj! - TODO - I'm supisious these time are getting confused on what units they are in
UInt64 now = Timer::getTimeSecs();
UInt64 ret = mExpires - now;
return (UInt32)ret;
}

friend class DialogSet [friend] |
Definition at line 101 of file ClientRegistration.hxx.
Definition at line 107 of file ClientRegistration.hxx.
Referenced by allContacts(), dispatch(), and removeAll().
bool resip::ClientRegistration::mEndWhenDone [private] |
Definition at line 111 of file ClientRegistration.hxx.
Referenced by checkProfileRetry(), dispatch(), removeAll(), and removeMyBindings().
UInt64 resip::ClientRegistration::mExpires [private] |
Definition at line 114 of file ClientRegistration.hxx.
Referenced by checkProfileRetry(), dispatch(), and whenExpires().
Definition at line 105 of file ClientRegistration.hxx.
Referenced by checkProfileRetry(), ClientRegistration(), dispatch(), dump(), internalRequestRefresh(), and tryModification().
Definition at line 106 of file ClientRegistration.hxx.
Referenced by addBinding(), ClientRegistration(), dispatch(), internalRequestRefresh(), myContacts(), removeAll(), removeBinding(), removeMyBindings(), rinstanceIsMine(), and searchByUri().
Definition at line 118 of file ClientRegistration.hxx.
Referenced by ClientRegistration(), dispatch(), and flowTerminated().
Definition at line 116 of file ClientRegistration.hxx.
Referenced by dispatch(), and tryModification().
State resip::ClientRegistration::mQueuedState [private] |
Definition at line 115 of file ClientRegistration.hxx.
Referenced by addBinding(), dispatch(), removeAll(), removeBinding(), removeMyBindings(), and tryModification().
Definition at line 113 of file ClientRegistration.hxx.
Referenced by addBinding(), calculateExpiry(), ClientRegistration(), dispatch(), and internalRequestRefresh().
State resip::ClientRegistration::mState [private] |
Definition at line 110 of file ClientRegistration.hxx.
Referenced by checkProfileRetry(), dispatch(), internalRequestRefresh(), removeAll(), removeBinding(), removeMyBindings(), and tryModification().
unsigned int resip::ClientRegistration::mTimerSeq [private] |
Definition at line 108 of file ClientRegistration.hxx.
Referenced by checkProfileRetry(), dispatch(), internalRequestRefresh(), and tryModification().
bool resip::ClientRegistration::mUserRefresh [private] |
Definition at line 112 of file ClientRegistration.hxx.
Referenced by dispatch(), and requestRefresh().
1.7.5.1