Dealing with REFERs

From reSIProcate
Revision as of 20:46, 26 April 2011 by Pckizer (talk | contribs) (convert the remaining code sections to syntax-highlighted forms)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Setup Required in order to Use REFER[edit]

  • To add support for the REFER method
 mProfile->addSupportedMethod(REFER);
  • To add support for receiving NOTIFY's with message/sipfrag bodies
 mProfile->addSupportedMimeType(NOTIFY, Mime("message", "sipfrag"));
  • To add support for REFER with replaces header
 mProfile->addSupportedOptionTag(Token(Symbols::Replaces));
  • To add support for REFER with no implied subscription
 mProfile->addSupportedOptionTag(Token(Symbols::NoReferSub));
  • To add support for reception of out-of-dialog REFERs
 mDum.addOutOfDialogHandler(REFER, mHandler);
  • To add Support for the implied server subscription when receiving a REFER
 mDum.addServerSubscriptionHandler("refer", mHandler);
  • To add Support for the implied client subscription when sending a REFER
 mDum.addClientSubscriptionHandler("refer", mHandler);


Initiating REFER Requests[edit]

  • To initiate an in-dialog REFER request (with implied subscription). Use the InviteSession::refer(referTo, true /* referSub? */) API.
  • To initiate an in-dialog REFER request (with no subscription). Use the InviteSession::refer(referTo, false /* referSub? */) API.
  • To initiate an out of dialog REFER request (with implied subscription). Use the DialogUsageManager::makeRefer() API.
  • To initiate an out of dialog REFER request (with no implied subscription). Use the DialogUsageManager::makeOutOfDialogRequest() API, and add the appropriate no-sub headers. ie:
  SharedPtr<SipMessage> refermsg = mDum.makeOutOfDialogRequest(target, userprofile, REFER, 0 /* AppDialogSet */);
  
  // Add refer To
  refermsg->header(h_ReferTo) = referTo;
  
  // Add ReferredBy header
  refermsg->header(h_ReferredBy) = mInviteSessionHandle->myAddr();
  refermsg->header(h_ReferredBy).remove(p_tag);   
  
  // Add No Sub indication
  refermsg->header(h_ReferSub).value() = "false";
  refermsg->header(h_Supporteds).push_back(Token(Symbols::NoReferSub));
  
  mDum.send(refermsg);

Handling REFER Requests[edit]

If an application wishes to process the REFER request it should use the dum->makeInviteSessionFromRefer API.

Sample Code:

 void onRefer(InviteSessionHandle is, ServerSubscriptionHandle ss, const SipMessage& msg)
 {
    ss->send(ss->accept(202));  // accept refer request
    SdpContents sdpOffer;
    ...  // build sdpOffer
    dum->send(dum->makeInviteSessionFromRefer(msg, ss, sdpOffer));  // send new INVITE
 }


Handling REFER with Replaces Requests[edit]

Sending REFER with Replaces[edit]

Use the InviteSession::refer(referTo, sessionToReplace) API - this will cause a REFER message to be sent to the other party that contains a Replaces header specifying the session to replace.

Receiving REFER with Replaces[edit]

For an application standpoint, this is handled in the exact same manner as receiving a REFER request without a Replaces header. If an application wishes to process the REFER request it should use the dum->makeInviteSessionFromRefer API.

Sample Code:

 void onRefer(InviteSessionHandle is, ServerSubscriptionHandle ss, const SipMessage& msg)
 {
    ss->send(ss->accept(202));  // accept refer request
    SdpContents sdpOffer;
    ...  // build sdpOffer
    dum->send(dum->makeInviteSessionFromRefer(msg, ss, sdpOffer));  // send new INVITE
 }

Receiving INVITE with Replaces[edit]

When you receive an INVITE request (via the onNewSession callback) you may wish to see if a Replace header is present, in order for this new INVITE session to "take over" an existing session. In order to accomplish this you can use a convience function on the DialogUsageManager called findInviteSession which takes a Replaces header as an argument.

Sample Code:

 void onNewSession(ServerInviteSession sis, InviteSession::OfferAnswerType oat, const SipMessage& msg)
 {
    if (msg->exists(h_Replaces))
    {
       pair<InviteSessionHandle, int> presult;
       presult = dum->findInviteSession(msg->header(h_Replaces));
       if (presult != InviteSessionHandle::NotValid())
       {
           ... // Do stuff in app to swap contexts
           Presult.first->end(); // end original session
       }
    }
    ...continue with app specific stuff
 }