|
reSIProcate/DialogUsageManager
9694
|
00001 #include "basicClientCall.hxx" 00002 00003 #include <resip/stack/SdpContents.hxx> 00004 #include <resip/stack/PlainContents.hxx> 00005 #include <resip/stack/SipMessage.hxx> 00006 #include <resip/stack/ShutdownMessage.hxx> 00007 #include <resip/stack/SipStack.hxx> 00008 #include <resip/dum/ClientAuthManager.hxx> 00009 #include <resip/dum/ClientInviteSession.hxx> 00010 #include <resip/dum/ClientSubscription.hxx> 00011 #include <resip/dum/DialogUsageManager.hxx> 00012 #include <resip/dum/InviteSessionHandler.hxx> 00013 #include <resip/dum/MasterProfile.hxx> 00014 #include <resip/dum/ServerInviteSession.hxx> 00015 #include <resip/dum/AppDialog.hxx> 00016 #include <resip/dum/AppDialogSet.hxx> 00017 #include <resip/dum/AppDialogSetFactory.hxx> 00018 #include <rutil/Log.hxx> 00019 #include <rutil/Logger.hxx> 00020 #include <rutil/Random.hxx> 00021 #include <rutil/WinLeakCheck.hxx> 00022 00023 #include <sstream> 00024 #include <time.h> 00025 00026 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST 00027 00028 using namespace resip; 00029 using namespace std; 00030 00031 static unsigned int CallTimerTime = 30; // Time between call timer 00032 static unsigned int CallTimeCounterToByeOn = 6; // BYE the call after the call timer has expired 6 times 00033 00034 namespace resip 00035 { 00036 class CallTimer : public resip::DumCommand 00037 { 00038 public: 00039 CallTimer(BasicClientUserAgent& userAgent, BasicClientCall* call) : mUserAgent(userAgent), mCall(call) {} 00040 CallTimer(const CallTimer& rhs) : mUserAgent(rhs.mUserAgent), mCall(rhs.mCall) {} 00041 ~CallTimer() {} 00042 00043 void executeCommand() { mUserAgent.onCallTimeout(mCall); } 00044 00045 resip::Message* clone() const { return new CallTimer(*this); } 00046 EncodeStream& encode(EncodeStream& strm) const { strm << "CallTimer:"; return strm; } 00047 EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } 00048 00049 private: 00050 BasicClientUserAgent& mUserAgent; 00051 BasicClientCall* mCall; 00052 }; 00053 } 00054 00055 BasicClientCall::BasicClientCall(BasicClientUserAgent& userAgent) 00056 : AppDialogSet(userAgent.getDialogUsageManager()), 00057 mUserAgent(userAgent), 00058 mTimerExpiredCounter(0), 00059 mPlacedCall(false), 00060 mUACConnectedDialogId(Data::Empty, Data::Empty, Data::Empty) 00061 { 00062 mUserAgent.registerCall(this); 00063 } 00064 00065 BasicClientCall::~BasicClientCall() 00066 { 00067 mUserAgent.unregisterCall(this); 00068 } 00069 00070 void 00071 BasicClientCall::initiateCall(const Uri& target, SharedPtr<UserProfile> profile) 00072 { 00073 SdpContents offer; 00074 makeOffer(offer); 00075 SharedPtr<SipMessage> invite = mUserAgent.getDialogUsageManager().makeInviteSession(NameAddr(target), profile, &offer, this); 00076 mUserAgent.getDialogUsageManager().send(invite); 00077 mPlacedCall = true; 00078 } 00079 00080 void 00081 BasicClientCall::terminateCall() 00082 { 00083 AppDialogSet::end(); 00084 } 00085 00086 void 00087 BasicClientCall::timerExpired() 00088 { 00089 mTimerExpiredCounter++; 00090 if(mTimerExpiredCounter < CallTimeCounterToByeOn) 00091 { 00092 // First few times, send a message to the other party 00093 if(mInviteSessionHandle.isValid()) 00094 { 00095 PlainContents plain("test message"); 00096 mInviteSessionHandle->message(plain); 00097 } 00098 } 00099 else 00100 { 00101 // Then hangup 00102 terminateCall(); 00103 } 00104 00105 // start timer for next one 00106 auto_ptr<ApplicationMessage> timer(new CallTimer(mUserAgent, this)); 00107 mUserAgent.mStack.post(timer, CallTimerTime, &mUserAgent.getDialogUsageManager()); 00108 } 00109 00110 SharedPtr<UserProfile> 00111 BasicClientCall::selectUASUserProfile(const SipMessage& msg) 00112 { 00113 return mUserAgent.getIncomingUserProfile(msg); 00114 } 00115 00116 bool 00117 BasicClientCall::isUACConnected() 00118 { 00119 return !mUACConnectedDialogId.getCallId().empty(); 00120 } 00121 00122 bool 00123 BasicClientCall::isStaleFork(const DialogId& dialogId) 00124 { 00125 return (!mUACConnectedDialogId.getCallId().empty() && dialogId != mUACConnectedDialogId); 00126 } 00127 00128 void 00129 BasicClientCall::makeOffer(SdpContents& offer) 00130 { 00131 static Data txt("v=0\r\n" 00132 "o=- 0 0 IN IP4 0.0.0.0\r\n" 00133 "s=basicClient\r\n" 00134 "c=IN IP4 0.0.0.0\r\n" 00135 "t=0 0\r\n" 00136 "m=audio 8000 RTP/AVP 0 101\r\n" 00137 "a=rtpmap:0 pcmu/8000\r\n" 00138 "a=rtpmap:101 telephone-event/8000\r\n" 00139 "a=fmtp:101 0-15\r\n"); 00140 00141 static HeaderFieldValue hfv(txt.data(), txt.size()); 00142 static Mime type("application", "sdp"); 00143 static SdpContents offerSdp(hfv, type); 00144 00145 offer = offerSdp; 00146 00147 // Set sessionid and version for this offer 00148 UInt64 currentTime = Timer::getTimeMicroSec(); 00149 offer.session().origin().getSessionId() = currentTime; 00150 offer.session().origin().getVersion() = currentTime; 00151 } 00152 00154 // InviteSessionHandler /////////////////////////////////////////////////// 00156 00157 void 00158 BasicClientCall::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg) 00159 { 00160 InfoLog(<< "onNewSession(ClientInviteSessionHandle): msg=" << msg.brief()); 00161 mInviteSessionHandle = h->getSessionHandle(); // Note: each forked leg will update mInviteSession - need to set mInviteSessionHandle for final answering leg on 200 00162 if(mInviteSessionHandleReplaced.isValid()) 00163 { 00164 // See comment in flowTerminated for an explanation of this logic 00165 ((BasicClientCall*)mInviteSessionHandleReplaced->getAppDialogSet().get())->terminateCall(); 00166 } 00167 } 00168 00169 void 00170 BasicClientCall::onNewSession(ServerInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg) 00171 { 00172 InfoLog(<< "onNewSession(ServerInviteSessionHandle): msg=" << msg.brief()); 00173 mInviteSessionHandle = h->getSessionHandle(); 00174 00175 // First check if this INVITE is to replace an existing session 00176 if(msg.exists(h_Replaces)) 00177 { 00178 pair<InviteSessionHandle, int> presult; 00179 presult = mDum.findInviteSession(msg.header(h_Replaces)); 00180 if(!(presult.first == InviteSessionHandle::NotValid())) 00181 { 00182 BasicClientCall* callToReplace = dynamic_cast<BasicClientCall *>(presult.first->getAppDialogSet().get()); 00183 InfoLog(<< "onNewSession(ServerInviteSessionHandle): replacing existing call"); 00184 00185 // Copy over flag that indicates if we placed the call or not 00186 mPlacedCall = callToReplace->mPlacedCall; 00187 00188 if(mPlacedCall) 00189 { 00190 // Restart Call Timer 00191 auto_ptr<ApplicationMessage> timer(new CallTimer(mUserAgent, this)); 00192 mUserAgent.mStack.post(timer, CallTimerTime, &mUserAgent.getDialogUsageManager()); 00193 } 00194 00195 // Session to replace was found - end old session 00196 callToReplace->end(); 00197 } 00198 else 00199 { 00200 // Session to replace not found - reject it 00201 h->reject(481 /* Call/Transaction Does Not Exist */); 00202 } 00203 } 00204 } 00205 00206 void 00207 BasicClientCall::onFailure(ClientInviteSessionHandle h, const SipMessage& msg) 00208 { 00209 WarningLog(<< "onFailure: msg=" << msg.brief()); 00210 00211 if (msg.isResponse()) 00212 { 00213 switch(msg.header(h_StatusLine).statusCode()) 00214 { 00215 case 408: 00216 case 503: 00217 if(msg.getReceivedTransport() == 0) 00218 { 00219 // Try another flow? 00220 } 00221 default: 00222 break; 00223 } 00224 } 00225 } 00226 00227 void 00228 BasicClientCall::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) 00229 { 00230 InfoLog(<< "onEarlyMedia: msg=" << msg.brief() << ", sdp=" << sdp); 00231 } 00232 00233 void 00234 BasicClientCall::onProvisional(ClientInviteSessionHandle h, const SipMessage& msg) 00235 { 00236 InfoLog(<< "onProvisional: msg=" << msg.brief()); 00237 00238 if(isStaleFork(h->getDialogId())) 00239 { 00240 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it 00241 InfoLog(<< "onProvisional: from stale fork, msg=" << msg.brief()); 00242 return; 00243 } 00244 InfoLog(<< "onProvisional: msg=" << msg.brief()); 00245 } 00246 00247 void 00248 BasicClientCall::onConnected(ClientInviteSessionHandle h, const SipMessage& msg) 00249 { 00250 InfoLog(<< "onConnected: msg=" << msg.brief()); 00251 if(!isUACConnected()) 00252 { 00253 // It is possible in forking scenarios to get multiple 200 responses, if this is 00254 // our first 200 response, then this is the leg we accept, store the connected DialogId 00255 mUACConnectedDialogId = h->getDialogId(); 00256 // Note: each forked leg will update mInviteSessionHandle (in onNewSession call) - need to set mInviteSessionHandle for final answering leg on 200 00257 mInviteSessionHandle = h->getSessionHandle(); 00258 00259 // start call timer 00260 auto_ptr<ApplicationMessage> timer(new CallTimer(mUserAgent, this)); 00261 mUserAgent.mStack.post(timer, CallTimerTime, &mUserAgent.getDialogUsageManager()); 00262 } 00263 else 00264 { 00265 // We already have a connected leg - end this one with a BYE 00266 h->end(); 00267 } 00268 } 00269 00270 void 00271 BasicClientCall::onConnected(InviteSessionHandle h, const SipMessage& msg) 00272 { 00273 InfoLog(<< "onConnected: msg=" << msg.brief()); 00274 } 00275 00276 void 00277 BasicClientCall::onStaleCallTimeout(ClientInviteSessionHandle h) 00278 { 00279 WarningLog(<< "onStaleCallTimeout"); 00280 } 00281 00282 void 00283 BasicClientCall::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg) 00284 { 00285 Data reasonData; 00286 00287 switch(reason) 00288 { 00289 case InviteSessionHandler::RemoteBye: 00290 reasonData = "received a BYE from peer"; 00291 break; 00292 case InviteSessionHandler::RemoteCancel: 00293 reasonData = "received a CANCEL from peer"; 00294 break; 00295 case InviteSessionHandler::Rejected: 00296 reasonData = "received a rejection from peer"; 00297 break; 00298 case InviteSessionHandler::LocalBye: 00299 reasonData = "ended locally via BYE"; 00300 break; 00301 case InviteSessionHandler::LocalCancel: 00302 reasonData = "ended locally via CANCEL"; 00303 break; 00304 case InviteSessionHandler::Replaced: 00305 reasonData = "ended due to being replaced"; 00306 break; 00307 case InviteSessionHandler::Referred: 00308 reasonData = "ended due to being referred"; 00309 break; 00310 case InviteSessionHandler::Error: 00311 reasonData = "ended due to an error"; 00312 break; 00313 case InviteSessionHandler::Timeout: 00314 reasonData = "ended due to a timeout"; 00315 break; 00316 default: 00317 assert(false); 00318 break; 00319 } 00320 00321 if(isStaleFork(h->getDialogId())) 00322 { 00323 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it 00324 if(msg) 00325 { 00326 InfoLog(<< "onTerminated: from stale fork, reason=" << reasonData << ", msg=" << msg->brief()); 00327 } 00328 else 00329 { 00330 InfoLog(<< "onTerminated: from stale fork, reason=" << reasonData); 00331 } 00332 return; 00333 } 00334 00335 if(msg) 00336 { 00337 InfoLog(<< "onTerminated: reason=" << reasonData << ", msg=" << msg->brief()); 00338 } 00339 else 00340 { 00341 InfoLog(<< "onTerminated: reason=" << reasonData); 00342 } 00343 } 00344 00345 void 00346 BasicClientCall::onRedirected(ClientInviteSessionHandle h, const SipMessage& msg) 00347 { 00348 // DUM will recurse on redirect requests, so nothing to do here 00349 InfoLog(<< "onRedirected: msg=" << msg.brief()); 00350 } 00351 00352 void 00353 BasicClientCall::onAnswer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) 00354 { 00355 if(isStaleFork(h->getDialogId())) 00356 { 00357 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it 00358 InfoLog(<< "onAnswer: from stale fork, msg=" << msg.brief() << ", sdp=" << sdp); 00359 return; 00360 } 00361 InfoLog(<< "onAnswer: msg=" << msg.brief() << ", sdp=" << sdp); 00362 00363 // Process Answer here 00364 } 00365 00366 void 00367 BasicClientCall::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) 00368 { 00369 if(isStaleFork(h->getDialogId())) 00370 { 00371 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it 00372 InfoLog(<< "onOffer: from stale fork, msg=" << msg.brief() << ", sdp=" << sdp); 00373 return; 00374 } 00375 InfoLog(<< "onOffer: msg=" << msg.brief() << ", sdp=" << sdp); 00376 00377 // Provide Answer here - for test client just echo back same SDP as received for now 00378 h->provideAnswer(sdp); 00379 ServerInviteSession* uas = dynamic_cast<ServerInviteSession*>(h.get()); 00380 if(uas && !uas->isAccepted()) 00381 { 00382 uas->accept(); 00383 } 00384 } 00385 00386 void 00387 BasicClientCall::onOfferRequired(InviteSessionHandle h, const SipMessage& msg) 00388 { 00389 if(isStaleFork(h->getDialogId())) 00390 { 00391 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it 00392 InfoLog(<< "onOfferRequired: from stale fork, msg=" << msg.brief()); 00393 return; 00394 } 00395 InfoLog(<< "onOfferRequired: msg=" << msg.brief()); 00396 00397 // Provide Offer Here 00398 SdpContents offer; 00399 makeOffer(offer); 00400 00401 h->provideOffer(offer); 00402 } 00403 00404 void 00405 BasicClientCall::onOfferRejected(InviteSessionHandle h, const SipMessage* msg) 00406 { 00407 if(isStaleFork(h->getDialogId())) 00408 { 00409 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it 00410 if(msg) 00411 { 00412 WarningLog(<< "onOfferRejected: from stale fork, msg=" << msg->brief()); 00413 } 00414 else 00415 { 00416 WarningLog(<< "onOfferRejected: from stale fork"); 00417 } 00418 return; 00419 } 00420 if(msg) 00421 { 00422 WarningLog(<< "onOfferRejected: msg=" << msg->brief()); 00423 } 00424 else 00425 { 00426 WarningLog(<< "onOfferRejected"); 00427 } 00428 } 00429 00430 void 00431 BasicClientCall::onOfferRequestRejected(InviteSessionHandle h, const SipMessage& msg) 00432 { 00433 InfoLog(<< "onOfferRequestRejected: msg=" << msg.brief()); 00434 // This is called when we are waiting to resend a INVITE with no sdp after a glare condition, and we 00435 // instead receive an inbound INVITE or UPDATE 00436 } 00437 00438 void 00439 BasicClientCall::onRemoteSdpChanged(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) 00440 { 00446 InfoLog(<< "onRemoteSdpChanged: msg=" << msg << ", sdp=" << sdp); 00447 00448 // Process SDP Answer here 00449 } 00450 00451 void 00452 BasicClientCall::onInfo(InviteSessionHandle h, const SipMessage& msg) 00453 { 00454 InfoLog(<< "onInfo: msg=" << msg.brief()); 00455 00456 // Handle message here 00457 h->acceptNIT(); 00458 } 00459 00460 void 00461 BasicClientCall::onInfoSuccess(InviteSessionHandle h, const SipMessage& msg) 00462 { 00463 InfoLog(<< "onInfoSuccess: msg=" << msg.brief()); 00464 } 00465 00466 void 00467 BasicClientCall::onInfoFailure(InviteSessionHandle h, const SipMessage& msg) 00468 { 00469 WarningLog(<< "onInfoFailure: msg=" << msg.brief()); 00470 } 00471 00472 void 00473 BasicClientCall::onRefer(InviteSessionHandle h, ServerSubscriptionHandle ss, const SipMessage& msg) 00474 { 00475 InfoLog(<< "onRefer: msg=" << msg.brief()); 00476 00477 // Handle Refer request here 00478 } 00479 00480 void 00481 BasicClientCall::onReferAccepted(InviteSessionHandle h, ClientSubscriptionHandle csh, const SipMessage& msg) 00482 { 00483 InfoLog(<< "onReferAccepted: msg=" << msg.brief()); 00484 } 00485 00486 void 00487 BasicClientCall::onReferRejected(InviteSessionHandle h, const SipMessage& msg) 00488 { 00489 WarningLog(<< "onReferRejected: msg=" << msg.brief()); 00490 } 00491 00492 void 00493 BasicClientCall::onReferNoSub(InviteSessionHandle h, const SipMessage& msg) 00494 { 00495 InfoLog(<< "onReferNoSub: msg=" << msg.brief()); 00496 00497 // Handle Refer request with (no-subscription indication) here 00498 } 00499 00500 void 00501 BasicClientCall::onMessage(InviteSessionHandle h, const SipMessage& msg) 00502 { 00503 InfoLog(<< "onMessage: msg=" << msg.brief()); 00504 00505 // Handle message here 00506 h->acceptNIT(); 00507 00508 if(!mPlacedCall) 00509 { 00510 // If we didn't place the call - answer the message with another message 00511 PlainContents plain("test message answer"); 00512 h->message(plain); 00513 } 00514 } 00515 00516 void 00517 BasicClientCall::onMessageSuccess(InviteSessionHandle h, const SipMessage& msg) 00518 { 00519 InfoLog(<< "onMessageSuccess: msg=" << msg.brief()); 00520 } 00521 00522 void 00523 BasicClientCall::onMessageFailure(InviteSessionHandle h, const SipMessage& msg) 00524 { 00525 WarningLog(<< "onMessageFailure: msg=" << msg.brief()); 00526 } 00527 00528 void 00529 BasicClientCall::onForkDestroyed(ClientInviteSessionHandle h) 00530 { 00531 InfoLog(<< "onForkDestroyed:"); 00532 } 00533 00534 void 00535 BasicClientCall::onReadyToSend(InviteSessionHandle h, SipMessage& msg) 00536 { 00537 } 00538 00539 void 00540 BasicClientCall::onFlowTerminated(InviteSessionHandle h) 00541 { 00542 if(h->isConnected()) 00543 { 00544 NameAddr inviteWithReplacesTarget; 00545 if(h->remoteTarget().uri().exists(p_gr)) 00546 { 00547 // If remote contact is a GRUU then use it 00548 inviteWithReplacesTarget.uri() = h->remoteTarget().uri(); 00549 } 00550 else 00551 { 00552 //.Use remote AOR 00553 inviteWithReplacesTarget.uri() = h->peerAddr().uri(); 00554 } 00555 InfoLog(<< "BasicClientCall::onFlowTerminated: trying INVITE w/replaces to " << inviteWithReplacesTarget); 00556 // The flow terminated - try an Invite (with Replaces) to recover the call 00557 BasicClientCall *replacesCall = new BasicClientCall(mUserAgent); 00558 00559 // Copy over flag that indicates wether original call was placed or received 00560 replacesCall->mPlacedCall = mPlacedCall; 00561 00562 // Note: We want to end this call since it is to be replaced. Normally the endpoint 00563 // receiving the INVITE with replaces would send us a BYE for the session being replaced. 00564 // However, since the old flow is dead, we will never see this BYE. We need this call to 00565 // go away somehow, however we cannot just end it directly here via terminateCall. 00566 // Since the flow to other party is likely fine - if we terminate this call now the BYE 00567 // is very likely to make it to the far end, before the above INVITE - if this happens then 00568 // the replaces logic of the INVITE will have no effect. We want to delay the release of 00569 // this call, by passing our handle to the new INVITE call and have it terminate this call, 00570 // once we know the far end has processed our new INVITE. 00571 replacesCall->mInviteSessionHandleReplaced = mInviteSessionHandle; 00572 00573 SdpContents offer; 00574 replacesCall->makeOffer(offer); 00575 SharedPtr<SipMessage> invite = mUserAgent.getDialogUsageManager().makeInviteSession(inviteWithReplacesTarget, h, getUserProfile(), &offer, replacesCall); 00576 mUserAgent.getDialogUsageManager().send(invite); 00577 } 00578 } 00579 00581 // DialogSetHandler /////////////////////////////////////////////////// 00583 void 00584 BasicClientCall::onTrying(AppDialogSetHandle h, const SipMessage& msg) 00585 { 00586 InfoLog(<< "onTrying: msg=" << msg.brief()); 00587 if(isUACConnected()) return; // Ignore 100's if already connected 00588 00589 // Handle message here 00590 } 00591 00592 void 00593 BasicClientCall::onNonDialogCreatingProvisional(AppDialogSetHandle h, const SipMessage& msg) 00594 { 00595 InfoLog(<< "onNonDialogCreatingProvisional: msg=" << msg.brief()); 00596 if(isUACConnected()) return; // Ignore provionals if already connected 00597 00598 // Handle message here 00599 } 00600 00602 // ClientSubscriptionHandler /////////////////////////////////////////////////// 00604 void 00605 BasicClientCall::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) 00606 { 00607 InfoLog(<< "onUpdatePending(ClientSubscriptionHandle): " << msg.brief()); 00608 if (msg.exists(h_Event) && msg.header(h_Event).value() == "refer") 00609 { 00610 //process Refer Notify Here 00611 } 00612 h->acceptUpdate(); 00613 } 00614 00615 void 00616 BasicClientCall::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) 00617 { 00618 InfoLog(<< "onUpdateActive(ClientSubscriptionHandle): " << msg.brief()); 00619 if (msg.exists(h_Event) && msg.header(h_Event).value() == "refer") 00620 { 00621 //process Refer Notify Here 00622 } 00623 h->acceptUpdate(); 00624 } 00625 00626 void 00627 BasicClientCall::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) 00628 { 00629 InfoLog(<< "onUpdateExtension(ClientSubscriptionHandle): " << msg.brief()); 00630 if (msg.exists(h_Event) && msg.header(h_Event).value() == "refer") 00631 { 00632 //process Refer Notify Here 00633 } 00634 h->acceptUpdate(); 00635 } 00636 00637 void 00638 BasicClientCall::onNotifyNotReceived(resip::ClientSubscriptionHandle h) 00639 { 00640 InfoLog(<< "onNotifyNotReceived(ClientSubscriptionHandle)"); 00641 h->end(); 00642 } 00643 00644 void 00645 BasicClientCall::onTerminated(ClientSubscriptionHandle h, const SipMessage* msg) 00646 { 00647 if(msg) 00648 { 00649 InfoLog(<< "onTerminated(ClientSubscriptionHandle): " << msg->brief()); 00650 //Note: Final notify is sometimes only passed in the onTerminated callback 00651 if (msg->isRequest() && msg->exists(h_Event) && msg->header(h_Event).value() == "refer") 00652 { 00653 //process Refer Notify Here 00654 } 00655 } 00656 else 00657 { 00658 InfoLog(<< "onTerminated(ClientSubscriptionHandle)"); 00659 } 00660 } 00661 00662 void 00663 BasicClientCall::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& msg) 00664 { 00665 InfoLog(<< "onNewSubscription(ClientSubscriptionHandle): " << msg.brief()); 00666 } 00667 00668 int 00669 BasicClientCall::onRequestRetry(ClientSubscriptionHandle h, int retrySeconds, const SipMessage& msg) 00670 { 00671 InfoLog(<< "onRequestRetry(ClientSubscriptionHandle): " << msg.brief()); 00672 return -1; 00673 } 00674 00675 void 00676 BasicClientCall::onRedirectReceived(AppDialogSetHandle h, const SipMessage& msg) 00677 { 00678 InfoLog(<< "onRedirectReceived: msg=" << msg.brief()); 00679 } 00680 00681 00682 /* ==================================================================== 00683 00684 Copyright (c) 2011, SIP Spectrum, Inc. 00685 All rights reserved. 00686 00687 Redistribution and use in source and binary forms, with or without 00688 modification, are permitted provided that the following conditions are 00689 met: 00690 00691 1. Redistributions of source code must retain the above copyright 00692 notice, this list of conditions and the following disclaimer. 00693 00694 2. Redistributions in binary form must reproduce the above copyright 00695 notice, this list of conditions and the following disclaimer in the 00696 documentation and/or other materials provided with the distribution. 00697 00698 3. Neither the name of SIP Spectrum nor the names of its contributors 00699 may be used to endorse or promote products derived from this 00700 software without specific prior written permission. 00701 00702 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00703 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00704 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00705 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00706 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00707 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00708 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00709 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00710 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00711 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00712 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00713 00714 ==================================================================== */
1.7.5.1