|
reSIProcate/DialogUsageManager
9694
|
00001 #ifdef HAVE_CONFIG_H 00002 #include "config.h" 00003 #endif 00004 00005 #include <rutil/Log.hxx> 00006 #include <rutil/Logger.hxx> 00007 #include <rutil/DnsUtil.hxx> 00008 #include <rutil/MD5Stream.hxx> 00009 #include <resip/stack/SdpContents.hxx> 00010 #include <resip/stack/PlainContents.hxx> 00011 #include <resip/stack/ConnectionTerminated.hxx> 00012 #include <resip/stack/Helper.hxx> 00013 #include <resip/dum/AppDialogSetFactory.hxx> 00014 #include <resip/dum/ClientAuthManager.hxx> 00015 #include <resip/dum/KeepAliveManager.hxx> 00016 #include <resip/dum/ClientInviteSession.hxx> 00017 #include <resip/dum/ServerInviteSession.hxx> 00018 #include <resip/dum/ClientSubscription.hxx> 00019 #include <resip/dum/ServerSubscription.hxx> 00020 #include <resip/dum/ClientRegistration.hxx> 00021 #include <resip/dum/ServerRegistration.hxx> 00022 #include <resip/dum/ServerOutOfDialogReq.hxx> 00023 #include <rutil/dns/AresDns.hxx> 00024 00025 #if defined (USE_SSL) 00026 #if defined(WIN32) 00027 #include "resip/stack/ssl/WinSecurity.hxx" 00028 #else 00029 #include "resip/stack/ssl/Security.hxx" 00030 #endif 00031 #endif 00032 00033 #include "basicClientUserAgent.hxx" 00034 #include "basicClientCall.hxx" 00035 00036 using namespace resip; 00037 using namespace std; 00038 00039 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST 00040 00041 static unsigned int MaxRegistrationRetryTime = 1800; // RFC5626 section 4.5 default 00042 static unsigned int BaseRegistrationRetryTimeAllFlowsFailed = 30; // RFC5626 section 4.5 default 00043 //static unsigned int BaseRegistrationRetryTime = 90; // RFC5626 section 4.5 default 00044 static unsigned int NotifySendTime = 30; // If someone subscribes to our test event package, then send notifies every 30 seconds 00045 static unsigned int FailedSubscriptionRetryTime = 60; 00046 00047 //#define TEST_PASSING_A1_HASH_FOR_PASSWORD 00048 00049 namespace resip 00050 { 00051 class ClientAppDialogSetFactory : public AppDialogSetFactory 00052 { 00053 public: 00054 ClientAppDialogSetFactory(BasicClientUserAgent& ua) : mUserAgent(ua) {} 00055 resip::AppDialogSet* createAppDialogSet(DialogUsageManager& dum, const SipMessage& msg) 00056 { 00057 switch(msg.method()) 00058 { 00059 case INVITE: 00060 return new BasicClientCall(mUserAgent); 00061 break; 00062 default: 00063 return AppDialogSetFactory::createAppDialogSet(dum, msg); 00064 break; 00065 } 00066 } 00067 private: 00068 BasicClientUserAgent& mUserAgent; 00069 }; 00070 00071 // Used to set the IP Address in outbound SDP to match the IP address choosen by the stack to send the message on 00072 class SdpMessageDecorator : public MessageDecorator 00073 { 00074 public: 00075 virtual ~SdpMessageDecorator() {} 00076 virtual void decorateMessage(SipMessage &msg, 00077 const Tuple &source, 00078 const Tuple &destination, 00079 const Data& sigcompId) 00080 { 00081 SdpContents* sdp = dynamic_cast<SdpContents*>(msg.getContents()); 00082 if(sdp) 00083 { 00084 // Fill in IP and Port from source 00085 sdp->session().connection().setAddress(Tuple::inet_ntop(source), source.ipVersion() == V6 ? SdpContents::IP6 : SdpContents::IP4); 00086 sdp->session().origin().setAddress(Tuple::inet_ntop(source), source.ipVersion() == V6 ? SdpContents::IP6 : SdpContents::IP4); 00087 InfoLog( << "SdpMessageDecorator: src=" << source << ", dest=" << destination << ", msg=" << endl << msg.brief()); 00088 } 00089 } 00090 virtual void rollbackMessage(SipMessage& msg) {} // Nothing to do 00091 virtual MessageDecorator* clone() const { return new SdpMessageDecorator; } 00092 }; 00093 00094 class NotifyTimer : public resip::DumCommand 00095 { 00096 public: 00097 NotifyTimer(BasicClientUserAgent& userAgent, unsigned int timerId) : mUserAgent(userAgent), mTimerId(timerId) {} 00098 NotifyTimer(const NotifyTimer& rhs) : mUserAgent(rhs.mUserAgent), mTimerId(rhs.mTimerId) {} 00099 ~NotifyTimer() {} 00100 00101 void executeCommand() { mUserAgent.onNotifyTimeout(mTimerId); } 00102 00103 resip::Message* clone() const { return new NotifyTimer(*this); } 00104 EncodeStream& encode(EncodeStream& strm) const { strm << "NotifyTimer: id=" << mTimerId; return strm; } 00105 EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } 00106 00107 private: 00108 BasicClientUserAgent& mUserAgent; 00109 unsigned int mTimerId; 00110 }; 00111 } // end namespace 00112 00113 BasicClientUserAgent::BasicClientUserAgent(int argc, char** argv) : 00114 BasicClientCmdLineParser(argc, argv), 00115 mProfile(new MasterProfile), 00116 #if defined(USE_SSL) 00117 mSecurity(new Security(mCertPath)), 00118 #else 00119 mSecurity(0), 00120 #endif 00121 mStack(mSecurity, DnsStub::EmptyNameserverList, &mSelectInterruptor), 00122 mDum(new DialogUsageManager(mStack)), 00123 mStackThread(mStack, mSelectInterruptor), 00124 mDumShutdownRequested(false), 00125 mDumShutdown(false), 00126 mRegistrationRetryDelayTime(0), 00127 mCurrentNotifyTimerId(0) 00128 { 00129 Log::initialize(mLogType, mLogLevel, argv[0]); 00130 00131 if(mHostFileLookupOnlyDnsMode) 00132 { 00133 AresDns::enableHostFileLookupOnlyMode(true); 00134 } 00135 00136 addTransport(UDP, mUdpPort); 00137 addTransport(TCP, mTcpPort); 00138 #if defined(USE_SSL) 00139 addTransport(TLS, mTlsPort); 00140 #endif 00141 #if defined(USE_DTLS) 00142 addTransport(DTLS, mDtlsPort); 00143 #endif 00144 00145 // Disable Statistics Manager 00146 mStack.statisticsManagerEnabled() = false; 00147 00148 // Supported Methods 00149 mProfile->clearSupportedMethods(); 00150 mProfile->addSupportedMethod(INVITE); 00151 mProfile->addSupportedMethod(ACK); 00152 mProfile->addSupportedMethod(CANCEL); 00153 mProfile->addSupportedMethod(OPTIONS); 00154 mProfile->addSupportedMethod(BYE); 00155 //mProfile->addSupportedMethod(REFER); 00156 mProfile->addSupportedMethod(NOTIFY); 00157 mProfile->addSupportedMethod(SUBSCRIBE); 00158 //mProfile->addSupportedMethod(UPDATE); 00159 mProfile->addSupportedMethod(INFO); 00160 mProfile->addSupportedMethod(MESSAGE); 00161 //mProfile->addSupportedMethod(PRACK); 00162 //mProfile->addSupportedOptionTag(Token(Symbols::C100rel)); // Automatically added when using setUacReliableProvisionalMode 00163 mProfile->setUacReliableProvisionalMode(MasterProfile::Supported); 00164 //mProfile->setUasReliableProvisionalMode(MasterProfile::Supported); // TODO - needs support in DUM, currently unimplemented 00165 00166 // Support Languages 00167 mProfile->clearSupportedLanguages(); 00168 mProfile->addSupportedLanguage(Token("en")); 00169 00170 // Support Mime Types 00171 mProfile->clearSupportedMimeTypes(); 00172 mProfile->addSupportedMimeType(INVITE, Mime("application", "sdp")); 00173 mProfile->addSupportedMimeType(INVITE, Mime("multipart", "mixed")); 00174 mProfile->addSupportedMimeType(INVITE, Mime("multipart", "signed")); 00175 mProfile->addSupportedMimeType(INVITE, Mime("multipart", "alternative")); 00176 mProfile->addSupportedMimeType(OPTIONS,Mime("application", "sdp")); 00177 mProfile->addSupportedMimeType(OPTIONS,Mime("multipart", "mixed")); 00178 mProfile->addSupportedMimeType(OPTIONS, Mime("multipart", "signed")); 00179 mProfile->addSupportedMimeType(OPTIONS, Mime("multipart", "alternative")); 00180 mProfile->addSupportedMimeType(PRACK, Mime("application", "sdp")); 00181 mProfile->addSupportedMimeType(PRACK, Mime("multipart", "mixed")); 00182 mProfile->addSupportedMimeType(PRACK, Mime("multipart", "signed")); 00183 mProfile->addSupportedMimeType(PRACK, Mime("multipart", "alternative")); 00184 mProfile->addSupportedMimeType(UPDATE, Mime("application", "sdp")); 00185 mProfile->addSupportedMimeType(UPDATE, Mime("multipart", "mixed")); 00186 mProfile->addSupportedMimeType(UPDATE, Mime("multipart", "signed")); 00187 mProfile->addSupportedMimeType(UPDATE, Mime("multipart", "alternative")); 00188 mProfile->addSupportedMimeType(MESSAGE, Mime("text","plain")); // Invite session in-dialog routing testing 00189 mProfile->addSupportedMimeType(NOTIFY, Mime("text","plain")); // subscription testing 00190 //mProfile->addSupportedMimeType(NOTIFY, Mime("message", "sipfrag")); 00191 00192 // Supported Options Tags 00193 mProfile->clearSupportedOptionTags(); 00194 //mMasterProfile->addSupportedOptionTag(Token(Symbols::Replaces)); 00195 mProfile->addSupportedOptionTag(Token(Symbols::Timer)); // Enable Session Timers 00196 if(mOutboundEnabled) 00197 { 00198 mProfile->addSupportedOptionTag(Token(Symbols::Outbound)); // RFC 5626 - outbound 00199 mProfile->addSupportedOptionTag(Token(Symbols::Path)); // RFC 3327 - path 00200 } 00201 //mMasterProfile->addSupportedOptionTag(Token(Symbols::NoReferSub)); 00202 //mMasterProfile->addSupportedOptionTag(Token(Symbols::TargetDialog)); 00203 00204 // Supported Schemes 00205 mProfile->clearSupportedSchemes(); 00206 mProfile->addSupportedScheme("sip"); 00207 #if defined(USE_SSL) 00208 mProfile->addSupportedScheme("sips"); 00209 #endif 00210 00211 // Validation Settings 00212 mProfile->validateContentEnabled() = false; 00213 mProfile->validateContentLanguageEnabled() = false; 00214 mProfile->validateAcceptEnabled() = false; 00215 00216 // Have stack add Allow/Supported/Accept headers to INVITE dialog establishment messages 00217 mProfile->clearAdvertisedCapabilities(); // Remove Profile Defaults, then add our preferences 00218 mProfile->addAdvertisedCapability(Headers::Allow); 00219 //mProfile->addAdvertisedCapability(Headers::AcceptEncoding); // This can be misleading - it might specify what is expected in response 00220 mProfile->addAdvertisedCapability(Headers::AcceptLanguage); 00221 mProfile->addAdvertisedCapability(Headers::Supported); 00222 mProfile->setMethodsParamEnabled(true); 00223 00224 // Install Sdp Message Decorator 00225 SharedPtr<MessageDecorator> outboundDecorator(new SdpMessageDecorator); 00226 mProfile->setOutboundDecorator(outboundDecorator); 00227 00228 // Other Profile Settings 00229 mProfile->setUserAgent("basicClient/1.0"); 00230 mProfile->setDefaultRegistrationTime(mRegisterDuration); 00231 mProfile->setDefaultRegistrationRetryTime(120); 00232 if(!mContact.host().empty()) 00233 { 00234 mProfile->setOverrideHostAndPort(mContact); 00235 } 00236 if(!mOutboundProxy.host().empty()) 00237 { 00238 mProfile->setOutboundProxy(Uri(mOutboundProxy)); 00239 //mProfile->setForceOutboundProxyOnAllRequestsEnabled(true); 00240 mProfile->setExpressOutboundAsRouteSetEnabled(true); 00241 } 00242 00243 // UserProfile Settings 00244 mProfile->setDefaultFrom(NameAddr(mAor)); 00245 #ifdef TEST_PASSING_A1_HASH_FOR_PASSWORD 00246 MD5Stream a1; 00247 a1 << mAor.user() 00248 << Symbols::COLON 00249 << mAor.host() 00250 << Symbols::COLON 00251 << mPassword; 00252 mProfile->setDigestCredential(mAor.host(), mAor.user(), a1.getHex(), true); 00253 #else 00254 mProfile->setDigestCredential(mAor.host(), mAor.user(), mPassword); 00255 #endif 00256 // Generate InstanceId appropriate for testing only. Should be UUID that persists 00257 // across machine re-starts and is unique to this applicaiton instance. The one used 00258 // here is only as unique as the hostname of this machine. If someone runs two 00259 // instances of this application on the same host for the same Aor, then things will 00260 // break. See RFC5626 section 4.1 00261 Data hostname = DnsUtil::getLocalHostName(); 00262 Data instanceHash = hostname.md5().uppercase(); 00263 assert(instanceHash.size() == 32); 00264 Data instanceId(48, Data::Preallocate); 00265 instanceId += "<urn:uuid:"; 00266 instanceId += instanceHash.substr(0, 8); 00267 instanceId += "-"; 00268 instanceId += instanceHash.substr(8, 4); 00269 instanceId += "-"; 00270 instanceId += instanceHash.substr(12, 4); 00271 instanceId += "-"; 00272 instanceId += instanceHash.substr(16, 4); 00273 instanceId += "-"; 00274 instanceId += instanceHash.substr(20, 12); 00275 instanceId += ">"; 00276 mProfile->setInstanceId(instanceId); 00277 if(mOutboundEnabled) 00278 { 00279 mProfile->setRegId(1); 00280 mProfile->clientOutboundEnabled() = true; 00281 } 00282 00283 // Install Managers 00284 mDum->setClientAuthManager(std::auto_ptr<ClientAuthManager>(new ClientAuthManager)); 00285 mDum->setKeepAliveManager(std::auto_ptr<KeepAliveManager>(new KeepAliveManager)); 00286 mProfile->setKeepAliveTimeForDatagram(30); 00287 mProfile->setKeepAliveTimeForStream(120); 00288 00289 // Install Handlers 00290 mDum->setInviteSessionHandler(this); 00291 mDum->setDialogSetHandler(this); 00292 mDum->addOutOfDialogHandler(OPTIONS, this); 00293 //mDum->addOutOfDialogHandler(REFER, this); 00294 mDum->setRedirectHandler(this); 00295 mDum->setClientRegistrationHandler(this); 00296 mDum->addClientSubscriptionHandler("basicClientTest", this); // fabricated test event package 00297 mDum->addServerSubscriptionHandler("basicClientTest", this); 00298 00299 // Set AppDialogSetFactory 00300 auto_ptr<AppDialogSetFactory> dsf(new ClientAppDialogSetFactory(*this)); 00301 mDum->setAppDialogSetFactory(dsf); 00302 00303 mDum->setMasterProfile(mProfile); 00304 00305 mDum->registerForConnectionTermination(this); 00306 } 00307 00308 BasicClientUserAgent::~BasicClientUserAgent() 00309 { 00310 mStackThread.shutdown(); 00311 mStackThread.join(); 00312 00313 delete mDum; 00314 } 00315 00316 void 00317 BasicClientUserAgent::startup() 00318 { 00319 mStackThread.run(); 00320 00321 if (mRegisterDuration) 00322 { 00323 InfoLog (<< "register for " << mAor); 00324 mDum->send(mDum->makeRegistration(NameAddr(mAor))); 00325 } 00326 else 00327 { 00328 // If not registering then form subscription and/or call here. If registering then we will start these 00329 // after the registration is successful. 00330 00331 // Check if we should try to form a test subscription 00332 if(!mSubscribeTarget.host().empty()) 00333 { 00334 SharedPtr<SipMessage> sub = mDum->makeSubscription(NameAddr(mSubscribeTarget), mProfile, "basicClientTest"); 00335 mDum->send(sub); 00336 } 00337 00338 // Check if we should try to form a test call 00339 if(!mCallTarget.host().empty()) 00340 { 00341 BasicClientCall* newCall = new BasicClientCall(*this); 00342 newCall->initiateCall(mCallTarget, mProfile); 00343 } 00344 } 00345 } 00346 00347 void 00348 BasicClientUserAgent::shutdown() 00349 { 00350 assert(mDum); 00351 mDumShutdownRequested = true; // Set flag so that shutdown operations can be run in dum process thread 00352 } 00353 00354 bool 00355 BasicClientUserAgent::process(int timeoutMs) 00356 { 00357 if(!mDumShutdown) 00358 { 00359 if(mDumShutdownRequested) 00360 { 00361 // unregister 00362 if(mRegHandle.isValid()) 00363 { 00364 mRegHandle->end(); 00365 } 00366 00367 // end any subscriptions 00368 if(mServerSubscriptionHandle.isValid()) 00369 { 00370 mServerSubscriptionHandle->end(); 00371 } 00372 if(mClientSubscriptionHandle.isValid()) 00373 { 00374 mClientSubscriptionHandle->end(); 00375 } 00376 00377 // End all calls - copy list in case delete/unregister of call is immediate 00378 std::set<BasicClientCall*> tempCallList = mCallList; 00379 std::set<BasicClientCall*>::iterator it = tempCallList.begin(); 00380 for(; it != tempCallList.end(); it++) 00381 { 00382 (*it)->terminateCall(); 00383 } 00384 00385 mDum->shutdown(this); 00386 mDumShutdownRequested = false; 00387 } 00388 mDum->process(timeoutMs); 00389 return true; 00390 } 00391 return false; 00392 } 00393 00394 void 00395 BasicClientUserAgent::addTransport(TransportType type, int port) 00396 { 00397 if(port == 0) return; // Transport disabled 00398 00399 for (int i=0; i < 10; ++i) 00400 { 00401 try 00402 { 00403 if (!mNoV4) 00404 { 00405 mStack.addTransport(type, port+i, V4, StunEnabled, Data::Empty, mTlsDomain); 00406 return; 00407 } 00408 00409 if (mEnableV6) 00410 { 00411 mStack.addTransport(type, port+i, V6, StunEnabled, Data::Empty, mTlsDomain); 00412 return; 00413 } 00414 } 00415 catch (BaseException& e) 00416 { 00417 InfoLog (<< "Caught: " << e); 00418 WarningLog (<< "Failed to add " << Tuple::toData(type) << " transport on " << port); 00419 } 00420 } 00421 throw Transport::Exception("Port already in use", __FILE__, __LINE__); 00422 } 00423 00424 void 00425 BasicClientUserAgent::post(Message* msg) 00426 { 00427 ConnectionTerminated* terminated = dynamic_cast<ConnectionTerminated*>(msg); 00428 if (terminated) 00429 { 00430 InfoLog(<< "BasicClientUserAgent received connection terminated message for: " << terminated->getFlow()); 00431 delete msg; 00432 return; 00433 } 00434 assert(false); 00435 } 00436 00437 void 00438 BasicClientUserAgent::onNotifyTimeout(unsigned int timerId) 00439 { 00440 if(timerId == mCurrentNotifyTimerId) 00441 { 00442 sendNotify(); 00443 } 00444 } 00445 00446 void 00447 BasicClientUserAgent::sendNotify() 00448 { 00449 if(mServerSubscriptionHandle.isValid()) 00450 { 00451 PlainContents plain("test notify"); 00452 mServerSubscriptionHandle->send(mServerSubscriptionHandle->update(&plain)); 00453 00454 // start timer for next one 00455 auto_ptr<ApplicationMessage> timer(new NotifyTimer(*this, ++mCurrentNotifyTimerId)); 00456 mStack.post(timer, NotifySendTime, mDum); 00457 } 00458 } 00459 00460 void 00461 BasicClientUserAgent::onCallTimeout(BasicClientCall* call) 00462 { 00463 if(isValidCall(call)) 00464 { 00465 call->timerExpired(); 00466 } 00467 else // call no longer exists 00468 { 00469 // If there are no more calls, then start a new one 00470 if(mCallList.empty() && !mCallTarget.host().empty()) 00471 { 00472 // re-start a new call 00473 BasicClientCall* newCall = new BasicClientCall(*this); 00474 newCall->initiateCall(mCallTarget, mProfile); 00475 } 00476 } 00477 } 00478 00479 void 00480 BasicClientUserAgent::registerCall(BasicClientCall* call) 00481 { 00482 mCallList.insert(call); 00483 } 00484 00485 void 00486 BasicClientUserAgent::unregisterCall(BasicClientCall* call) 00487 { 00488 std::set<BasicClientCall*>::iterator it = mCallList.find(call); 00489 if(it != mCallList.end()) 00490 { 00491 mCallList.erase(it); 00492 } 00493 } 00494 00495 bool 00496 BasicClientUserAgent::isValidCall(BasicClientCall* call) 00497 { 00498 std::set<BasicClientCall*>::iterator it = mCallList.find(call); 00499 if(it != mCallList.end()) 00500 { 00501 return true; 00502 } 00503 return false; 00504 } 00505 00506 void 00507 BasicClientUserAgent::onDumCanBeDeleted() 00508 { 00509 mDumShutdown = true; 00510 } 00511 00513 // Registration Handler //////////////////////////////////////////////////////// 00515 void 00516 BasicClientUserAgent::onSuccess(ClientRegistrationHandle h, const SipMessage& msg) 00517 { 00518 InfoLog(<< "onSuccess(ClientRegistrationHandle): msg=" << msg.brief()); 00519 if(mRegHandle.getId() == 0) // Note: reg handle id will only be 0 on first successful registration 00520 { 00521 // Check if we should try to form a test subscription 00522 if(!mSubscribeTarget.host().empty()) 00523 { 00524 SharedPtr<SipMessage> sub = mDum->makeSubscription(NameAddr(mSubscribeTarget), mProfile, "basicClientTest"); 00525 mDum->send(sub); 00526 } 00527 00528 // Check if we should try to form a test call 00529 if(!mCallTarget.host().empty()) 00530 { 00531 BasicClientCall* newCall = new BasicClientCall(*this); 00532 newCall->initiateCall(mCallTarget, mProfile); 00533 } 00534 } 00535 mRegHandle = h; 00536 mRegistrationRetryDelayTime = 0; // reset 00537 } 00538 00539 void 00540 BasicClientUserAgent::onFailure(ClientRegistrationHandle h, const SipMessage& msg) 00541 { 00542 InfoLog(<< "onFailure(ClientRegistrationHandle): msg=" << msg.brief()); 00543 mRegHandle = h; 00544 } 00545 00546 void 00547 BasicClientUserAgent::onRemoved(ClientRegistrationHandle h, const SipMessage&msg) 00548 { 00549 InfoLog(<< "onRemoved(ClientRegistrationHandle): msg=" << msg.brief()); 00550 mRegHandle = h; 00551 } 00552 00553 int 00554 BasicClientUserAgent::onRequestRetry(ClientRegistrationHandle h, int retryMinimum, const SipMessage& msg) 00555 { 00556 mRegHandle = h; 00557 00558 if(mRegistrationRetryDelayTime == 0) 00559 { 00560 mRegistrationRetryDelayTime = BaseRegistrationRetryTimeAllFlowsFailed; // We only have one flow in this test app 00561 } 00562 00563 // Use back off procedures of RFC 5626 section 4.5 00564 mRegistrationRetryDelayTime = resipMin(MaxRegistrationRetryTime, mRegistrationRetryDelayTime * 2); 00565 00566 // return an evenly distributed random number between 50% and 100% of mRegistrationRetryDelayTime 00567 int retryTime = Helper::jitterValue(mRegistrationRetryDelayTime, 50, 100); 00568 InfoLog(<< "onRequestRetry(ClientRegistrationHandle): msg=" << msg.brief() << ", retryTime=" << retryTime); 00569 00570 return retryTime; 00571 } 00572 00573 00575 // InviteSessionHandler //////////////////////////////////////////////////////// 00577 void 00578 BasicClientUserAgent::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg) 00579 { 00580 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onNewSession(h, oat, msg); 00581 } 00582 00583 void 00584 BasicClientUserAgent::onNewSession(ServerInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg) 00585 { 00586 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onNewSession(h, oat, msg); 00587 } 00588 00589 void 00590 BasicClientUserAgent::onFailure(ClientInviteSessionHandle h, const SipMessage& msg) 00591 { 00592 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onFailure(h, msg); 00593 } 00594 00595 void 00596 BasicClientUserAgent::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) 00597 { 00598 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onEarlyMedia(h, msg, sdp); 00599 } 00600 00601 void 00602 BasicClientUserAgent::onProvisional(ClientInviteSessionHandle h, const SipMessage& msg) 00603 { 00604 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onProvisional(h, msg); 00605 } 00606 00607 void 00608 BasicClientUserAgent::onConnected(ClientInviteSessionHandle h, const SipMessage& msg) 00609 { 00610 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onConnected(h, msg); 00611 } 00612 00613 void 00614 BasicClientUserAgent::onConnected(InviteSessionHandle h, const SipMessage& msg) 00615 { 00616 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onConnected(h, msg); 00617 } 00618 00619 void 00620 BasicClientUserAgent::onStaleCallTimeout(ClientInviteSessionHandle h) 00621 { 00622 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onStaleCallTimeout(h); 00623 } 00624 00625 void 00626 BasicClientUserAgent::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg) 00627 { 00628 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onTerminated(h, reason, msg); 00629 } 00630 00631 void 00632 BasicClientUserAgent::onRedirected(ClientInviteSessionHandle h, const SipMessage& msg) 00633 { 00634 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onRedirected(h, msg); 00635 } 00636 00637 void 00638 BasicClientUserAgent::onAnswer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) 00639 { 00640 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onAnswer(h, msg, sdp); 00641 } 00642 00643 void 00644 BasicClientUserAgent::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) 00645 { 00646 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOffer(h, msg, sdp); 00647 } 00648 00649 void 00650 BasicClientUserAgent::onOfferRequired(InviteSessionHandle h, const SipMessage& msg) 00651 { 00652 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOfferRequired(h, msg); 00653 } 00654 00655 void 00656 BasicClientUserAgent::onOfferRejected(InviteSessionHandle h, const SipMessage* msg) 00657 { 00658 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOfferRejected(h, msg); 00659 } 00660 00661 void 00662 BasicClientUserAgent::onOfferRequestRejected(InviteSessionHandle h, const SipMessage& msg) 00663 { 00664 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOfferRequestRejected(h, msg); 00665 } 00666 00667 void 00668 BasicClientUserAgent::onRemoteSdpChanged(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) 00669 { 00670 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onRemoteSdpChanged(h, msg, sdp); 00671 } 00672 00673 void 00674 BasicClientUserAgent::onInfo(InviteSessionHandle h, const SipMessage& msg) 00675 { 00676 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onInfo(h, msg); 00677 } 00678 00679 void 00680 BasicClientUserAgent::onInfoSuccess(InviteSessionHandle h, const SipMessage& msg) 00681 { 00682 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onInfoSuccess(h, msg); 00683 } 00684 00685 void 00686 BasicClientUserAgent::onInfoFailure(InviteSessionHandle h, const SipMessage& msg) 00687 { 00688 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onInfoFailure(h, msg); 00689 } 00690 00691 void 00692 BasicClientUserAgent::onRefer(InviteSessionHandle h, ServerSubscriptionHandle ssh, const SipMessage& msg) 00693 { 00694 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onRefer(h, ssh, msg); 00695 } 00696 00697 void 00698 BasicClientUserAgent::onReferAccepted(InviteSessionHandle h, ClientSubscriptionHandle csh, const SipMessage& msg) 00699 { 00700 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReferAccepted(h, csh, msg); 00701 } 00702 00703 void 00704 BasicClientUserAgent::onReferRejected(InviteSessionHandle h, const SipMessage& msg) 00705 { 00706 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReferRejected(h, msg); 00707 } 00708 00709 void 00710 BasicClientUserAgent::onReferNoSub(InviteSessionHandle h, const SipMessage& msg) 00711 { 00712 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReferNoSub(h, msg); 00713 } 00714 00715 void 00716 BasicClientUserAgent::onMessage(InviteSessionHandle h, const SipMessage& msg) 00717 { 00718 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onMessage(h, msg); 00719 } 00720 00721 void 00722 BasicClientUserAgent::onMessageSuccess(InviteSessionHandle h, const SipMessage& msg) 00723 { 00724 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onMessageSuccess(h, msg); 00725 } 00726 00727 void 00728 BasicClientUserAgent::onMessageFailure(InviteSessionHandle h, const SipMessage& msg) 00729 { 00730 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onMessageFailure(h, msg); 00731 } 00732 00733 void 00734 BasicClientUserAgent::onForkDestroyed(ClientInviteSessionHandle h) 00735 { 00736 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onForkDestroyed(h); 00737 } 00738 00739 void 00740 BasicClientUserAgent::onReadyToSend(InviteSessionHandle h, SipMessage& msg) 00741 { 00742 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReadyToSend(h, msg); 00743 } 00744 00745 void 00746 BasicClientUserAgent::onFlowTerminated(InviteSessionHandle h) 00747 { 00748 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onFlowTerminated(h); 00749 } 00750 00751 00753 // DialogSetHandler /////////////////////////////////////////////////// 00755 void 00756 BasicClientUserAgent::onTrying(AppDialogSetHandle h, const SipMessage& msg) 00757 { 00758 BasicClientCall *call = dynamic_cast<BasicClientCall *>(h.get()); 00759 if(call) 00760 { 00761 call->onTrying(h, msg); 00762 } 00763 else 00764 { 00765 InfoLog(<< "onTrying(AppDialogSetHandle): " << msg.brief()); 00766 } 00767 } 00768 00769 void 00770 BasicClientUserAgent::onNonDialogCreatingProvisional(AppDialogSetHandle h, const SipMessage& msg) 00771 { 00772 BasicClientCall *call = dynamic_cast<BasicClientCall *>(h.get()); 00773 if(call) 00774 { 00775 call->onNonDialogCreatingProvisional(h, msg); 00776 } 00777 else 00778 { 00779 InfoLog(<< "onNonDialogCreatingProvisional(AppDialogSetHandle): " << msg.brief()); 00780 } 00781 } 00782 00784 // ClientSubscriptionHandler /////////////////////////////////////////////////// 00786 void 00787 BasicClientUserAgent::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) 00788 { 00789 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get()); 00790 if(call) 00791 { 00792 call->onUpdatePending(h, msg, outOfOrder); 00793 return; 00794 } 00795 InfoLog(<< "onUpdatePending(ClientSubscriptionHandle): " << msg.brief()); 00796 h->acceptUpdate(); 00797 } 00798 00799 void 00800 BasicClientUserAgent::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) 00801 { 00802 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get()); 00803 if(call) 00804 { 00805 call->onUpdateActive(h, msg, outOfOrder); 00806 return; 00807 } 00808 InfoLog(<< "onUpdateActive(ClientSubscriptionHandle): " << msg.brief()); 00809 h->acceptUpdate(); 00810 } 00811 00812 void 00813 BasicClientUserAgent::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) 00814 { 00815 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get()); 00816 if(call) 00817 { 00818 call->onUpdateExtension(h, msg, outOfOrder); 00819 return; 00820 } 00821 InfoLog(<< "onUpdateExtension(ClientSubscriptionHandle): " << msg.brief()); 00822 h->acceptUpdate(); 00823 } 00824 00825 void 00826 BasicClientUserAgent::onNotifyNotReceived(ClientSubscriptionHandle h) 00827 { 00828 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get()); 00829 if(call) 00830 { 00831 call->onNotifyNotReceived(h); 00832 return; 00833 } 00834 WarningLog(<< "onNotifyNotReceived(ClientSubscriptionHandle)"); 00835 h->end(); 00836 } 00837 00838 void 00839 BasicClientUserAgent::onTerminated(ClientSubscriptionHandle h, const SipMessage* msg) 00840 { 00841 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get()); 00842 if(call) 00843 { 00844 call->onTerminated(h, msg); 00845 return; 00846 } 00847 if(msg) 00848 { 00849 InfoLog(<< "onTerminated(ClientSubscriptionHandle): msg=" << msg->brief()); 00850 } 00851 else 00852 { 00853 InfoLog(<< "onTerminated(ClientSubscriptionHandle)"); 00854 } 00855 } 00856 00857 void 00858 BasicClientUserAgent::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& msg) 00859 { 00860 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get()); 00861 if(call) 00862 { 00863 call->onNewSubscription(h, msg); 00864 return; 00865 } 00866 mClientSubscriptionHandle = h; 00867 InfoLog(<< "onNewSubscription(ClientSubscriptionHandle): msg=" << msg.brief()); 00868 } 00869 00870 int 00871 BasicClientUserAgent::onRequestRetry(ClientSubscriptionHandle h, int retrySeconds, const SipMessage& msg) 00872 { 00873 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get()); 00874 if(call) 00875 { 00876 return call->onRequestRetry(h, retrySeconds, msg); 00877 } 00878 InfoLog(<< "onRequestRetry(ClientSubscriptionHandle): msg=" << msg.brief()); 00879 return FailedSubscriptionRetryTime; 00880 } 00881 00883 // ServerSubscriptionHandler /////////////////////////////////////////////////// 00885 void 00886 BasicClientUserAgent::onNewSubscription(ServerSubscriptionHandle h, const SipMessage& msg) 00887 { 00888 InfoLog(<< "onNewSubscription(ServerSubscriptionHandle): " << msg.brief()); 00889 00890 mServerSubscriptionHandle = h; 00891 mServerSubscriptionHandle->setSubscriptionState(Active); 00892 mServerSubscriptionHandle->send(mServerSubscriptionHandle->accept()); 00893 00894 sendNotify(); 00895 } 00896 00897 void 00898 BasicClientUserAgent::onNewSubscriptionFromRefer(ServerSubscriptionHandle ss, const SipMessage& msg) 00899 { 00900 InfoLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): " << msg.brief()); 00901 // Received an out-of-dialog refer request with implicit subscription 00902 try 00903 { 00904 if(msg.exists(h_ReferTo)) 00905 { 00906 // Check if TargetDialog header is present 00907 if(msg.exists(h_TargetDialog)) 00908 { 00909 pair<InviteSessionHandle, int> presult; 00910 presult = mDum->findInviteSession(msg.header(h_TargetDialog)); 00911 if(!(presult.first == InviteSessionHandle::NotValid())) 00912 { 00913 BasicClientCall* callToRefer = (BasicClientCall*)presult.first->getAppDialogSet().get(); 00914 00915 callToRefer->onRefer(presult.first, ss, msg); 00916 return; 00917 } 00918 } 00919 00920 // We don't support ood refers that don't target a dialog - reject request 00921 WarningLog (<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): Received ood refer (noSub) w/out a Target-Dialog: " << msg.brief()); 00922 ss->send(ss->reject(400)); 00923 } 00924 else 00925 { 00926 WarningLog (<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): Received refer w/out a Refer-To: " << msg.brief()); 00927 ss->send(ss->reject(400)); 00928 } 00929 } 00930 catch(BaseException &e) 00931 { 00932 WarningLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): exception " << e); 00933 } 00934 catch(...) 00935 { 00936 WarningLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): unknown exception"); 00937 } 00938 } 00939 00940 void 00941 BasicClientUserAgent::onRefresh(ServerSubscriptionHandle, const SipMessage& msg) 00942 { 00943 InfoLog(<< "onRefresh(ServerSubscriptionHandle): " << msg.brief()); 00944 } 00945 00946 void 00947 BasicClientUserAgent::onTerminated(ServerSubscriptionHandle) 00948 { 00949 InfoLog(<< "onTerminated(ServerSubscriptionHandle)"); 00950 } 00951 00952 void 00953 BasicClientUserAgent::onReadyToSend(ServerSubscriptionHandle, SipMessage&) 00954 { 00955 } 00956 00957 void 00958 BasicClientUserAgent::onNotifyRejected(ServerSubscriptionHandle, const SipMessage& msg) 00959 { 00960 WarningLog(<< "onNotifyRejected(ServerSubscriptionHandle): " << msg.brief()); 00961 } 00962 00963 void 00964 BasicClientUserAgent::onError(ServerSubscriptionHandle, const SipMessage& msg) 00965 { 00966 WarningLog(<< "onError(ServerSubscriptionHandle): " << msg.brief()); 00967 } 00968 00969 void 00970 BasicClientUserAgent::onExpiredByClient(ServerSubscriptionHandle, const SipMessage& sub, SipMessage& notify) 00971 { 00972 InfoLog(<< "onExpiredByClient(ServerSubscriptionHandle): " << notify.brief()); 00973 } 00974 00975 void 00976 BasicClientUserAgent::onExpired(ServerSubscriptionHandle, SipMessage& msg) 00977 { 00978 InfoLog(<< "onExpired(ServerSubscriptionHandle): " << msg.brief()); 00979 } 00980 00981 bool 00982 BasicClientUserAgent::hasDefaultExpires() const 00983 { 00984 return true; 00985 } 00986 00987 UInt32 00988 BasicClientUserAgent::getDefaultExpires() const 00989 { 00990 return 60; 00991 } 00992 00994 // OutOfDialogHandler ////////////////////////////////////////////////////////// 00996 void 00997 BasicClientUserAgent::onSuccess(ClientOutOfDialogReqHandle, const SipMessage& msg) 00998 { 00999 InfoLog(<< "onSuccess(ClientOutOfDialogReqHandle): " << msg.brief()); 01000 } 01001 01002 void 01003 BasicClientUserAgent::onFailure(ClientOutOfDialogReqHandle h, const SipMessage& msg) 01004 { 01005 WarningLog(<< "onFailure(ClientOutOfDialogReqHandle): " << msg.brief()); 01006 } 01007 01008 void 01009 BasicClientUserAgent::onReceivedRequest(ServerOutOfDialogReqHandle ood, const SipMessage& msg) 01010 { 01011 InfoLog(<< "onReceivedRequest(ServerOutOfDialogReqHandle): " << msg.brief()); 01012 01013 switch(msg.method()) 01014 { 01015 case OPTIONS: 01016 { 01017 SharedPtr<SipMessage> optionsAnswer = ood->answerOptions(); 01018 ood->send(optionsAnswer); 01019 break; 01020 } 01021 default: 01022 ood->send(ood->reject(501 /* Not Implemented*/)); 01023 break; 01024 } 01025 } 01026 01028 // RedirectHandler ///////////////////////////////////////////////////////////// 01030 void 01031 BasicClientUserAgent::onRedirectReceived(AppDialogSetHandle h, const SipMessage& msg) 01032 { 01033 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h.get()); 01034 if(call) 01035 { 01036 call->onRedirectReceived(h, msg); 01037 } 01038 else 01039 { 01040 InfoLog(<< "onRedirectReceived(AppDialogSetHandle): " << msg.brief()); 01041 } 01042 } 01043 01044 bool 01045 BasicClientUserAgent::onTryingNextTarget(AppDialogSetHandle, const SipMessage& msg) 01046 { 01047 InfoLog(<< "onTryingNextTarget(AppDialogSetHandle): " << msg.brief()); 01048 01049 // Always allow redirection for now 01050 return true; 01051 } 01052 01053 01054 01055 01056 /* ==================================================================== 01057 01058 Copyright (c) 2011, SIP Spectrum, Inc. 01059 All rights reserved. 01060 01061 Redistribution and use in source and binary forms, with or without 01062 modification, are permitted provided that the following conditions are 01063 met: 01064 01065 1. Redistributions of source code must retain the above copyright 01066 notice, this list of conditions and the following disclaimer. 01067 01068 2. Redistributions in binary form must reproduce the above copyright 01069 notice, this list of conditions and the following disclaimer in the 01070 documentation and/or other materials provided with the distribution. 01071 01072 3. Neither the name of SIP Spectrum nor the names of its contributors 01073 may be used to endorse or promote products derived from this 01074 software without specific prior written permission. 01075 01076 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 01077 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 01078 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 01079 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 01080 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 01081 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 01082 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 01083 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 01084 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 01085 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 01086 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 01087 01088 ==================================================================== */ 01089
1.7.5.1