📄 clientregistration.cxx
字号:
#include <algorithm>#include <iterator>#include "resip/stack/Helper.hxx"#include "resip/dum/BaseCreator.hxx"#include "resip/dum/ClientRegistration.hxx"#include "resip/dum/RegistrationHandler.hxx"#include "resip/dum/DialogUsageManager.hxx"#include "resip/dum/Dialog.hxx"#include "resip/dum/MasterProfile.hxx"#include "resip/dum/UsageUseException.hxx"#include "rutil/Logger.hxx"#include "rutil/Inserter.hxx"#include "rutil/Random.hxx"#include "rutil/ParseBuffer.hxx"#include "rutil/WinLeakCheck.hxx"#define RESIPROCATE_SUBSYSTEM Subsystem::DUMusing namespace resip;ClientRegistrationHandleClientRegistration::getHandle(){ return ClientRegistrationHandle(mDum, getBaseHandle().getId());}ClientRegistration::ClientRegistration(DialogUsageManager& dum, DialogSet& dialogSet, SharedPtr<SipMessage> request) : NonDialogUsage(dum, dialogSet), mLastRequest(request), mTimerSeq(0), mState(mLastRequest->exists(h_Contacts) ? Adding : Querying), mEndWhenDone(false), mUserRefresh(false), mRegistrationTime(mDialogSet.getUserProfile()->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(){ DebugLog ( << "ClientRegistration::~ClientRegistration" ); mDialogSet.mClientRegistration = 0; // !dcm! Will not interact well with multiple registrations from the same AOR getUserProfile()->setServiceRoute(NameAddrs());}voidClientRegistration::addBinding(const NameAddr& contact){ addBinding(contact, mDialogSet.getUserProfile()->getDefaultRegistrationTime());}SharedPtr<SipMessage>ClientRegistration::tryModification(ClientRegistration::State state){ 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;}voidClientRegistration::addBinding(const NameAddr& contact, UInt32 registrationTime){ SharedPtr<SipMessage> next = tryModification(Adding); mMyContacts.push_back(contact); if(mDialogSet.getUserProfile()->getRinstanceEnabled()) { mMyContacts.back().uri().param(p_rinstance) = Random::getCryptoRandomHex(8); // .slg. poor mans instance id so that we can tell which contacts are ours - to be replaced by gruu someday } 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); }}voidClientRegistration::removeBinding(const NameAddr& contact){ 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__);}voidClientRegistration::removeAll(bool stopRegisteringWhenDone){ 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); }}voidClientRegistration::removeMyBindings(bool stopRegisteringWhenDone){ 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); }}class ClientRegistrationRemoveMyBindings : public DumCommandAdapter{public: ClientRegistrationRemoveMyBindings(ClientRegistration& clientRegistration, bool stopRegisteringWhenDone) : mClientRegistration(clientRegistration), mStopRegisteringWhenDone(stopRegisteringWhenDone) { } virtual void executeCommand() { mClientRegistration.removeMyBindings(mStopRegisteringWhenDone); } virtual std::ostream& encodeBrief(std::ostream& strm) const { return strm << "ClientRegistrationRemoveMyBindings"; }private: ClientRegistration& mClientRegistration; bool mStopRegisteringWhenDone;};voidClientRegistration::removeMyBindingsCommand(bool stopRegisteringWhenDone){ mDum.post(new ClientRegistrationRemoveMyBindings(*this, stopRegisteringWhenDone));}void ClientRegistration::stopRegistering(){ //timers aren't a concern, as DUM checks for Handle validity before firing. delete this;}voidClientRegistration::requestRefresh(UInt32 expires){ // Set flag so that handlers get called for success/failure mUserRefresh = true; internalRequestRefresh(expires);}voidClientRegistration::internalRequestRefresh(UInt32 expires){ InfoLog (<< "requesting refresh of " << *this); assert (mState == Registered); 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(){ return mMyContacts;}const NameAddrs&ClientRegistration::allContacts(){ return mAllContacts;}UInt32ClientRegistration::whenExpires() const{// !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;}voidClientRegistration::end(){ removeMyBindings(true);}class ClientRegistrationEndCommand : public DumCommandAdapter{public: ClientRegistrationEndCommand(ClientRegistration& clientRegistration) : mClientRegistration(clientRegistration) { } virtual void executeCommand() { mClientRegistration.end(); } virtual std::ostream& encodeBrief(std::ostream& strm) const { return strm << "ClientRegistrationEndCommand"; }private: ClientRegistration& mClientRegistration;};voidClientRegistration::endCommand(){ mDum.post(new ClientRegistrationEndCommand(*this));}std::ostream& ClientRegistration::dump(std::ostream& strm) const{ strm << "ClientRegistration " << mLastRequest->header(h_From).uri(); return strm;}voidClientRegistration::dispatch(const SipMessage& msg){ try { // !jf! there may be repairable errors that we can handle here assert(msg.isResponse()); if(msg.isExternal()) { const Data& receivedTransport = msg.header(h_Vias).front().transport(); int keepAliveTime = 0; if(receivedTransport == Symbols::TCP || receivedTransport == Symbols::TLS || receivedTransport == Symbols::SCTP) { keepAliveTime = mDialogSet.getUserProfile()->getKeepAliveTimeForStream(); } else { keepAliveTime = mDialogSet.getUserProfile()->getKeepAliveTimeForDatagram(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -