Symbian3/SDK/Source/GUID-CF17532E-5E90-5124-8F05-AA72B848F17F.dita
changeset 7 51a74ef9ed63
child 8 ae94777fff8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-CF17532E-5E90-5124-8F05-AA72B848F17F.dita	Wed Mar 31 11:11:55 2010 +0100
@@ -0,0 +1,423 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-CF17532E-5E90-5124-8F05-AA72B848F17F" xml:lang="en"><title>SIP
+Example: Usage of the SIP Stack</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>The SIP sample application is a game that can be played between two users
+that use two different machines. The following figure illustrates the sample
+application. </p>
+<fig id="GUID-A0E243BE-E697-5856-8C08-6039AAE6A05A">
+<image href="GUID-155C5B39-CB9B-5405-B9BB-EB34CA7C43BC_d0e344859_href.png" placement="inline"/>
+</fig>
+<p>All users who want to play the game must register to the server with their
+identities. This informs the server that the user is active and prepared to
+participate in the game. If User 1 wants to play the game with User 2 then
+it must send a request to User 2 through the server. When User 2 accepts the
+request and acknowledges it then the two users can start playing. A user can
+disconnect from playing the game by sending a message. If a user wants to
+be deactivated then it can deregister from the server. </p>
+<p>This application is developed using the key features of the Symbian SIP
+stack. It shows how to create profiles and do SIP registration using the profiles,
+how to set up a SIP session and send an instant message using the SIP. For
+example you can set up the SIP server using Brekeke and you can download the
+same from <xref href="http://www.brekeke.com/download/download_sip_2_0.php" scope="external">http://www.brekeke.com/download/download_sip_2_0.php</xref>. </p>
+<section><title>Features of the game</title> <p>The main features of the game
+are: </p> <ul>
+<li id="GUID-8767E5EC-04F6-5D19-B77A-94C6E7BF10B7"><p> <b>Register or deregister </b> -
+A user registers to the server with a unique identity before playing the game.
+This identity is the SIP URI of the user. The user registers by sending a
+SIP REGISTER message to the SIP server and is active. A user deactivates by
+deregistering to the server. This activity is done by sending the SIP REGISTER
+message with the expires header set to 0. For more information on registering
+or deregistering to the server see, <xref href="GUID-CF17532E-5E90-5124-8F05-AA72B848F17F.dita#GUID-CF17532E-5E90-5124-8F05-AA72B848F17F/GUID-2C4A1BCE-CD8E-5BDC-84D1-2C5DDBF8A142">Registering
+or deregistering an user</xref>. </p> </li>
+<li id="GUID-1547D0C9-4B7C-568F-9C5D-A2BE20F9B362"><p> <b>Invite another user</b> -
+A user invites another user to play the game by entering the SIP URI of the
+other user in the INVITE message. For more information on inviting another
+user to play the game see, <xref href="GUID-CF17532E-5E90-5124-8F05-AA72B848F17F.dita#GUID-CF17532E-5E90-5124-8F05-AA72B848F17F/GUID-7D5CB45C-614B-58DF-8EE4-1AB2DB02CE1C">Inviting
+a participant for session setup</xref>. </p> </li>
+<li id="GUID-94802B8B-C10B-5ADB-A5E0-0FC436790427"><p> <b>Send a message to
+another user</b> - A user can send an instant message to another user. For
+more information on how to send an instant message to another user see, <xref href="GUID-CF17532E-5E90-5124-8F05-AA72B848F17F.dita#GUID-CF17532E-5E90-5124-8F05-AA72B848F17F/GUID-0E7C6F87-C90B-5888-B1F7-33ED0D7393F5">Sending
+an instant message</xref>. </p> </li>
+<li id="GUID-55484DA7-37DC-566B-95F8-066E19AA5790"><p> <b>Disconnect from
+playing the game</b> - A user can disconnect from playing the game by sending
+a SIP BYE message to the other user. </p> </li>
+</ul> </section>
+<section id="GUID-3A9BE5C5-A9A2-54A8-B525-6750E562EF97"><title>How to play
+the game</title> <p>The following snapshot shows the different tabs available
+in the game. </p> <fig id="GUID-15C8B95B-4B8C-5701-80B1-C0D7B39AF422">
+<image href="GUID-0E21EAE4-BF71-55FD-9561-EA5530696627_d0e344932_href.png" placement="inline"/>
+</fig> <p>The following list describes the different tabs available in the
+game: </p> <ul>
+<li id="GUID-CDB3E759-F01D-5D02-B8AA-7E901C1984BE"><p> <b>Invite for game</b> -
+This tab allows you to invite a user to play the game. When you invoke this
+tab, a UI screen appears which asks the user to provide the SIP URI of the
+second user with whom the user wants to play the game. The SIP URI of the
+second user is then sent to the SIP stack which passes on the invite request
+to the second user. The second user can accept or reject the invite. If the
+second user accepts the invite then it acknowledges by sending a message that
+it is prepared to start playing the game. If the second user rejects the invite
+then it cannot play the game. </p> </li>
+<li id="GUID-4A4F6318-1FDD-540A-BF87-72B19BE56A97"><p> <b>Enable profile</b> -
+This tab allows you to enable a profile. When you invoke this tab, a UI screen
+appears where the user enters the values. A profile is created using these
+values and the user registers with the SIP server. </p> </li>
+<li id="GUID-A9F95A0B-4E44-52C6-AD0B-E2BDFA4C8CCE"><p> <b>Send instant msg</b> -
+This tab allows you to send a message to another user. When you invoke this
+tab, a message with the address of the recipient is sent to the SIP stack.
+The SIP stack sends this message to the recipient address. </p> </li>
+<li id="GUID-4334DC63-8AAB-581C-A779-FBBBD44C4227"><p> <b>End game</b> - This
+tab allows you to disconnect from playing the game. When you invoke this tab,
+a BYE message is sent to the other user and the game is terminated. </p> </li>
+</ul> </section>
+<section id="GUID-2C4A1BCE-CD8E-5BDC-84D1-2C5DDBF8A142"><title>Registering
+or deregistering an user</title> <p>An application can register to the SIP
+Server using: </p> <ul>
+<li id="GUID-620D3765-E3A1-55B9-900F-562486A01D6B"><p>the <xref href="GUID-48AA01D5-CE7B-3C22-B2E0-529261121EC4.dita"><apiname>CSIPRegistrationBinding</apiname></xref> class
+and its methods </p> </li>
+<li id="GUID-DDC990A1-BFDC-5CA4-A392-EAADFB8C3921"><p>the SIP Profile Agent </p> </li>
+</ul> <p>This sample application uses the SIP Profile Agent method to do SIP
+registration. To use this method you need a SIP profile setting, and you must
+create a SIP profile before you start using the application. <b>Note</b>:
+A list of SIP profile settings can be found in the <xref href="GUID-68AE6070-0410-3671-9E68-A7785B8271CD.dita"><apiname>CSIPProfile</apiname></xref> class. </p> <p>The
+SIP profile agent method provides APIs for: </p> <ul>
+<li id="GUID-68A120EA-45B6-5909-8DD1-B125A1249C13"><p>Registering and Deregistering </p> </li>
+<li id="GUID-50AA5E67-EA40-5844-873B-77DAAE94480F"><p>Listening to registration
+events </p> </li>
+<li id="GUID-300245B5-2B62-5382-B492-8BE8759E48E3"><p>Creating, modifying,
+and deleting the SIP profile settings that the profile agent plug-in implementations
+use for SIP registration. </p> </li>
+</ul> <p>The following code from <filepath>SIPExProfileQueryDlg.cpp</filepath> shows
+how the sample application stores the settings entered by users on the SIP
+profile store. </p> <codeblock id="GUID-8D76FE52-F0E5-5F57-AD38-0AE8694D3AA4" xml:space="preserve">//Create a new profile
+    CSIPManagedProfile* profile = iMProfileRegistry-&gt;CreateL(iProfileData.iServiceProfile);
+   
+//Copy attributes entered by the user to the new profile        
+    iNewProfile = profile;
+    profile = CopyDataToProfileL();
+
+//Set the profile to default and save some settings
+    TInt err= profile-&gt;SetParameter(KSIPDefaultProfile,ETrue);
+   
+//Save the profile to persistent store                
+    iMProfileRegistry-&gt;SaveL( *profile );
+</codeblock> <p>The applications can start SIP registration or deregistration
+using the <codeph>Enable</codeph> or <codeph>Disable</codeph> methods from
+the SIP profile API. </p> <p>The following code from <filepath>SIPExSIPEngine.cpp</filepath> shows
+how to register using the profile agent. </p> <codeblock id="GUID-F4398335-6AC0-5E10-B04D-6846A3CDE1D5" xml:space="preserve">//Check for the existing profile
+    if ( iProfile )
+        {
+        delete iProfile;
+        iProfile = NULL;
+        }
+    TBool registered( EFalse );
+    
+//Leaves with KErrNotFound if default profile is not found
+    iProfile = iProfileRegistry-&gt;DefaultProfileL();
+ else
+        {
+        const TDesC8* aor = NULL;
+  iProfile-&gt;GetParameter( KSIPUserAor, aor );      
+  iProfileRegistry-&gt;EnableL( *iProfile, *this );
+
+    //Check if the profile was immediately set to the registered state
+    iProfile-&gt;GetParameter( KSIPProfileRegistered, registered );
+        }
+</codeblock> <p>The following code from <filepath>SIPExSIPEngine.cpp</filepath> shows
+how to deregister using the profile agent. </p> <codeblock id="GUID-B13F8581-D36B-5AE1-A821-84FD3B010575" xml:space="preserve">if ( iProfile )
+        {
+        iProfileRegistry-&gt;Disable( *iProfile );
+        delete iProfile;
+        iProfile = NULL;        
+        }</codeblock> <p>The SIP profile API also provides a notification
+method that is used by an application to monitor profile related events. </p> <p>The
+following code from <filepath>SIPExProfileQueryDlg.cpp</filepath> shows the
+profile related events that the sample applications monitors. </p> <codeblock id="GUID-34230A3A-EA20-56B9-AFC0-F9AC92BE2F3E" xml:space="preserve">void ProfileRegistryEventOccurred( 
+    TUint32 aProfileId, 
+    TEvent aEvent )
+    {
+    switch (aEvent)
+        {
+        case MSIPProfileRegistryObserver::EProfileRegistered:
+            {
+            HandleProfileRegistered( aProfileId );
+            break;
+            }
+        case MSIPProfileRegistryObserver::EProfileDeregistered:
+            {
+            HandleProfileDeregistered( aProfileId );
+            break;
+            }
+        case MSIPProfileRegistryObserver::EProfileDestroyed:
+            {
+            HandleProfileDestroyed( aProfileId );
+            break;
+            }
+        default:
+            {
+            // MSIPProfileRegistryObserver::EProfileCreated and MSIPProfileRegistryObserver::EProfileUpdated are ignored
+            break;
+            }
+        }
+    }
+void ProfileRegistryErrorOccurred( 
+    TUint32 /* aSIPProfileId */,
+    TInt aError )
+    {
+    iObserver-&gt;ProfileError( aError );
+    }
+</codeblock> <p><b>Classes containing APIs in scope</b> </p> <p> <xref href="GUID-68AE6070-0410-3671-9E68-A7785B8271CD.dita"><apiname>CSIPProfile</apiname></xref>, <xref href="GUID-CDE67614-1A7A-3082-8D8D-71645668A0DE.dita"><apiname>CSIPManagedProfile</apiname></xref>, <xref href="GUID-E8D080AD-4494-3880-B5CE-3487CA7D76E9.dita"><apiname>CSIPProfileRegistry</apiname></xref>, <xref href="GUID-5266AB0D-705C-3011-A92B-DA82BC212999.dita"><apiname>CSIPManagedProfileRegistry</apiname></xref>, <xref href="GUID-91663686-42B7-3C88-B773-3C5343CDCFCE.dita"><apiname>MSIPProfileRegistryObserver</apiname></xref>. </p> </section>
+<section id="GUID-7D5CB45C-614B-58DF-8EE4-1AB2DB02CE1C"><title>Inviting a
+participant for session setup</title> <p>The sample application uses the SIP
+INVITE method to setup a session between two users. In this case, the application
+does not accept any SDP parameters from the user and instead sends fixed SDP
+values. </p> <p>The following code from <filepath>SIPExSIPIdleState.cpp</filepath> shows
+how the application sends an INVITE message. </p> <codeblock id="GUID-B8E774F0-D6C0-5631-83E3-5D87DF03D044" xml:space="preserve">void SendInviteL( 
+    CSIPExSIPEngine&amp; aEngine,
+    const TDesC8&amp; aSipUri )
+    {
+    //Retrieve the active profile and connection
+    CSIPProfile&amp; prof = aEngine.Profile();
+    CSIPConnection&amp; conn = aEngine.ConnectionL();
+
+ //Create CUri8 from the passed descriptor. This value is given by the user
+    CUri8* uri8 = aEngine.ConvertToUri8LC( aSipUri );
+    
+    //Get dialog association, save for future use
+    //The ownership of uri8 is transferred
+    CSIPInviteDialogAssoc* dialogAssoc =
+        CSIPInviteDialogAssoc::NewL( conn, uri8, prof );
+        aEngine.SetDialogAssoc( *dialogAssoc ); //Ownership is transferred!!
+
+    //Create the necessary message elements
+    CSIPMessageElements* msgElements = aEngine.CreateMessageElementsLC();
+
+    //Send the INVITE in the dialog
+    //The ownership of msgElements is transferred
+    INVITE SENT OUT
+    CSIPClientTransaction* tx = dialogAssoc-&gt;SendInviteL( msgElements );
+ }
+</codeblock> </section>
+<section id="GUID-BADF4C98-FB28-50F1-AC00-F8764CBF2B12"><title>Handling an
+incoming invite</title> <p>An application that wants to receive an incoming
+invite outside the dialog must implement the Client Resolver API. The <xref href="GUID-14EC2BB8-AE94-3052-8A0B-039BA6E9C610.dita"><apiname>CSipResolvedClient</apiname></xref> (<filepath>SipResolvedClient.h</filepath>) interface is implemented by clients to enable a client resolution mechanism
+when the SIP requests are received outside the SIP dialog. The application
+must state the capabilities, that is the supported content types and media
+formats. This is done using the SIP headers and SDP m-lines either in the
+code of the plug-in, that is in <codeph>const KCapabilities</codeph> or in
+the opaque_data field of the resource file. </p> <p>The capabilities can be
+provided to the plug-ins in two ways: </p> <ul>
+<li id="GUID-04021FC9-D7F1-592E-A286-3E3C905880EB"><p>The data is provided
+in the ECOM resource file. </p> </li>
+<li id="GUID-ABBC862D-2930-5268-9FE9-2D8C7CA6C656"><p>In the interface implementation
+from where it is used to determine the target client. </p> </li>
+</ul> <p>The following code from <filepath>SIPExResolverPlugin.cpp</filepath> shows
+how the data is provided in the ECOM resource file. </p> <codeblock id="GUID-18FE5466-1BA2-57FD-BD3D-5818AFC35767" xml:space="preserve">#include &lt;RegistryInfo.rh&gt;
+RESOURCE REGISTRY_INFO theInfo
+    {
+    // UID for the DLL
+    dll_uid = 0xA00001EC;
+    // Declare array of interface info
+    interfaces = 
+        {
+        INTERFACE_INFO 
+            {
+            // UID of interface that is implemented
+            interface_uid = 0x102010DD;
+            implementations = 
+                {
+                IMPLEMENTATION_INFO
+                    {
+                    implementation_uid = 0xA00001EC;
+                    version_no = 1;
+                    // SIPEx UID: Must match to the one SIPEx passes to CSIP::NewL.    
+                    default_data = "A00001EB";
+                    }
+                };
+            }
+        };
+    }</codeblock> <p>The following code from <filepath>SIPExResolverPlugin.cpp</filepath> shows
+how the capabilities are defined in the plug-in. </p> <codeblock id="GUID-5D448F3C-CA4E-5EB2-9416-9383DC08A182" xml:space="preserve">//Code for defining capabilities in plugin
+//File : SIPExResolverPlugin.cpp
+
+_LIT8(KCapabilities,
+"&lt;SIP_CLIENT ALLOW_STARTING=\"YES\"&gt;\
+&lt;SIP_HEADERS&gt;\
+&lt;ACCEPT value=\"application/sdp\"/&gt;\
+&lt;ACCEPT value=\"SIPEx/InstantMessage\"/&gt;\
+&lt;/SIP_HEADERS&gt;\
+&lt;SDP_LINES&gt;\
+&lt;LINE name=\"m\" value=\"application 0 TCP SIPEx\"/&gt;\
+&lt;/SDP_LINES&gt;\
+&lt;/SIP_CLIENT&gt;");
+
+
+</codeblock> <p>When there is an incoming <codeph>Invite Request</codeph> with
+SDP parameters the SIP stack passes the request to the Client Resolver to
+get the resolved client for that request. The Client Resolver gets the capabilities
+for all the applications that implement the Client Resolver API. </p> <p>The
+following code from <filepath>SIPExResolverPlugin.cpp</filepath> shows how
+to get the capabilities for an application. </p> <codeblock id="GUID-819B95EE-5D9E-5BF6-BE49-1E00C3144CB8" xml:space="preserve">//Code for obtaining capabilities for an application
+//File : SIPExResolverPlugin.cpp
+
+const TDesC8&amp; CSIPExResolverPlugin::Capabilities()
+    {
+    return KCapabilities;
+    }</codeblock> <p>When the target client is identified, the Client Resolver
+gets the ChannelID from the plug-in implementation and requests the resolved
+client to connect to the SIP implementation on that UID. <b>Note</b>: The
+ChannelID is same as Application UID3 </p> <p>The following code from <filepath>SIPExResolverPlugin.cpp</filepath> shows
+how to get ChannelID for an application. </p> <codeblock id="GUID-3516BAD9-E116-59AA-9424-AEA7FB0DDADA" xml:space="preserve">//Code for obtaining ChannelID for an application
+//File : SIPExResolverPlugin.cpp
+  
+  TUid CSIPExResolverPlugin::ChannelL( RStringF /*aMethod*/,
+    const TDesC8&amp; /*aRequestUri*/,
+    const RPointerArray&lt;CSIPHeaderBase&gt;&amp; /*aHeaders*/,
+    const TDesC8&amp; /*aContent*/,
+    const CSIPContentTypeHeader* /*aContentType*/)
+    {
+    return iApplicationUID;
+    }
+
+//Code for asking an application to connect on UID 
+//File : SIPExResolverPlugin.cpp
+
+ void CSIPExResolverPlugin::ConnectL( TUid aUid )
+    {
+    //Launch application is based on UID passed from the SIP stack
+    
+    TApaAppInfo appInfo;
+    User::LeaveIfError( iApaSession.GetAppInfo( appInfo, aUid ) );
+    CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
+#ifdef EKA2
+    cmdLine-&gt;SetExecutableNameL( appInfo.iFullName );
+#else
+    cmdLine-&gt;SetLibraryNameL( appInfo.iFullName );
+#endif
+    User::LeaveIfError( iApaSession.StartApp( *cmdLine ) );
+    CleanupStack::PopAndDestroy( cmdLine ); 
+    }</codeblock> <p>When the resolved client connects, the INVITE is forwarded
+to the client and it starts ringing (180 Ringing) and sends the provisional
+response to the calling party. This part is implemented in <xref href="GUID-D891F857-2AE0-3112-8A9D-8648F98F96AC.dita"><apiname>InviteReceivedL</apiname></xref> as
+shown in the following code. </p> <p>The following code from <filepath>SIPExSIPIdleState.cpp</filepath> shows
+how the application gets the INVITE and how the provisional response is sent. </p> <codeblock id="GUID-7775ADCE-4351-5D50-BD91-85C0FEBF47E5" xml:space="preserve">/Code for CSIPExSIPIdleState::InviteReceivedL()... 
+//File : SIPExSIPIdleState.cpp    
+
+void CSIPExSIPIdleState::InviteReceivedL( 
+    CSIPExSIPEngine&amp; aEngine,
+    CSIPServerTransaction* aTransaction )
+    {
+    _LIT8( KLogEntry, "180 Ringing sent" );
+    ..
+    ..
+    aEngine.Observer()-&gt;WriteLog( KLogEntry );
+    ..
+   }</codeblock> <p>From this stage, the INVITE is sent to <codeph>InviteReceived</codeph> of <codeph>CSIPExEngine</codeph> in <filepath>SIPExGameEngine.cpp</filepath> from where it asks from the game observer if the user has accepted the invitation
+or not. The game starts or does not start depends on action taken. </p> <p>The
+following code from <filepath>SIPExStateRegistered.cpp</filepath> shows how
+the acceptance is asked from the game observer. </p> <codeblock id="GUID-224959DA-DF2D-5969-85E1-2B71DC32C176" xml:space="preserve">//The acceptance is asked from the user and if accepted the game is reset, start
+//listening socket and signal the SIP engine to send Accepted to the remote peer.
+
+//File : SIPExStateRegistered.cpp
+
+void TSIPExStateRegistered::InviteReceived( 
+    CSIPExEngine* aContext, 
+    const TDesC8&amp; aFrom, 
+    const TUint32 aIapId )
+    {
+    iEnded = EFalse;
+    
+    TBool retVal( EFalse );
+    TRAPD( ignore, retVal = aContext-&gt;AcceptInvitationL( aFrom ) );
+    if ( iEnded )
+        {
+        return;
+        }
+    if( retVal )
+        {
+        StatusInfo( aContext, KGameStarting() );
+        ChangeState( aContext, aContext-&gt;iStateAcceptingSIP );
+        aContext-&gt;ResetGame();
+        aContext-&gt;SetPeer( CSIPExEngine::EServer );
+        Info( aContext, KListening() );
+        TInetAddr addr;
+        TRAP( ignore, addr = 
+                        aContext-&gt;SocketEngineL()-&gt;StartListeningL( aIapId ) );
+        Info( aContext, KAccepting() );
+        TRAP( ignore, aContext-&gt;SIPEngine()-&gt;AcceptInviteL( addr ) );
+        Info( aContext, KWaitingRemoteConn() );
+        }
+    else 
+        {
+        TRAP( ignore, aContext-&gt;SIPEngine()-&gt;DeclineInviteL() );
+        Info( aContext, KInviteDeclined() );
+        }
+    }
+</codeblock> <p>When the game observer accepts the invitation the following
+code from <filepath>SIPExGameEngine.cpp</filepath> is run. </p> <codeblock id="GUID-91EF56AD-266F-5EE8-B8C0-37C1A6529C48" xml:space="preserve">//File : SIPExGameEngine.cpp
+
+TBool CSIPExEngine::AcceptInvitationL( const TDesC8&amp; aFrom )
+    {
+    HBufC* from = HBufC::NewLC( aFrom.Length() );
+    from-&gt;Des().Copy( aFrom );
+    TBool retVal = iGameObserver.AcceptInvitationL( *from );
+    CleanupStack::PopAndDestroy( from );
+    return retVal;
+    }</codeblock> </section>
+<section id="GUID-0E7C6F87-C90B-5888-B1F7-33ED0D7393F5"><title>Sending an
+instant message</title> <p>This sample application allows a user to send an
+Instant Message (IM) to another user. The user requires SIP URI of the other
+user and the message content that the user must enter. The application then
+creates a MESSAGE (request message) with these parameters and uses <xref href="GUID-D8168DEA-50CC-342B-AEF1-4703B50794A6.dita"><apiname>SendRequestL()</apiname></xref> to
+send it. </p> <p>The following code from <filepath>SIPExSIPEngine.cpp</filepath> shows
+how to send an instant message. </p> <codeblock id="GUID-641C6039-11B4-5389-8876-D817D5541CCE" xml:space="preserve">//Create and send an instant message to a recipient defined with the parameters.
+//This is implemented with the MESSAGE method and is sent outside of a dialog.
+
+CreateIML(const TDesC8&amp; aMessage,
+    const TDesC8&amp; aSipUri )
+    {
+    _LIT8( KMediaType, "SIPEx" );    // Part of content type
+    _LIT8( KMediaSubType, "InstantMessage" );    // Part of content type
+
+//Create the necessary elements of the IM
+    
+CSIPRequestElements* reqElem = CreateReqElementsLC( aSipUri );
+    CSIPToHeader* toHeader = CreateToHeaderLC( aSipUri );
+    reqElem-&gt;SetToHeaderL( toHeader );
+    
+//Create the fromHeader value using the information from the profile
+
+ const TDesC8* aor = NULL;
+ iProfile-&gt;GetParameter( KSIPUserAor, aor ); 
+ CSIPAddress* addr = CSIPAddress::DecodeL( *aor );
+ CSIPFromHeader* fromHeader = CSIPFromHeader::NewL( addr );
+ reqElem-&gt;SetFromHeaderL( fromHeader );
+ reqElem-&gt;SetMethodL( SIPStrings::StringF( SipStrConsts::EMessage ) );
+
+//Get reference to the message elements from the request elements, create and insert content type header (ownership of the content type object is transferred)
+
+    CSIPMessageElements&amp; msgElem = reqElem-&gt;MessageElements();
+    CSIPContentTypeHeader* ct =    CSIPContentTypeHeader::NewLC( KMediaType, KMediaSubType );
+    msgElem.SetContentL( aMessage.AllocL(), ct );
+    
+//Get the current connection
+
+CSIPConnection&amp; conn = ConnectionL();
+
+//Send the request using the connection (ownership of the request elements object is transferred)
+
+    CSIPClientTransaction* ctx = conn.SendRequestL( reqElem );
+    delete ctx;
+    }
+
+</codeblock> <p><b>Classes containing APIs in scope</b> </p> <p> <xref href="GUID-19FB031A-CFA7-3C67-A627-CFF501060AA5.dita"><apiname>CSIPRequestElements</apiname></xref>, <xref href="GUID-7B5D0432-5C2C-3EFB-B9FA-8B4A0AA68FC0.dita"><apiname>CSIPToHeader</apiname></xref>, <xref href="GUID-AFEC85BE-5971-3043-B9A9-24048346AADE.dita"><apiname>CSIPFromHeader</apiname></xref>, <xref href="GUID-F8BF1190-F5D4-31EF-B060-A1430AA07DAC.dita"><apiname>CSIPAddress</apiname></xref>, <xref href="GUID-77CFD812-7238-3B84-80FF-475BD73C3506.dita"><apiname>CSIPMessageElements</apiname></xref>, <xref href="GUID-059F9C3A-EA04-3295-912F-50444F073CE7.dita"><apiname>CSIPClientTransaction</apiname></xref>. </p> </section>
+</conbody></concept>
\ No newline at end of file