S60 3rd Edition SDK for Symbian OS
Example Applications Guide

SIPExSIPEngine.cpp

00001 /*
00002 * ==============================================================================
00003 *  Name        : SIPExSIPEngine.cpp
00004 *  Part of     : SIPExSIPEngine
00005 *  Interface   : 
00006 *  Description : 
00007 *  Version     : 
00008 *
00009 *  Copyright (c) 2004-2006 Nokia Corporation.
00010 *  This material, including documentation and any related 
00011 *  computer programs, is protected by copyright controlled by 
00012 *  Nokia Corporation.
00013 * ==============================================================================
00014 */
00015 
00016 // INCLUDE FILES
00017 
00018 #include "SIPExSIPEngine.h"
00019 #include "SIPExSIPStateBase.h"
00020 
00021 #include <Uri8.h>
00022 #include <sipstrings.h>
00023 #include <SipStrConsts.h>
00024 
00025 // CONSTANTS
00026 
00027 _LIT8( KSdpNoInfoDesC8, "-" );
00028 
00029 // ============================ MEMBER FUNCTIONS ===============================
00030 
00031 // -----------------------------------------------------------------------------
00032 // CSIPExSIPEngine::NewL
00033 // Two-phased constructor.
00034 // -----------------------------------------------------------------------------
00035 EXPORT_C CSIPExSIPEngine* CSIPExSIPEngine::NewL( 
00036     TUid aAppUid,
00037         MSIPExSIPEngineObserver* aObserver )
00038         {
00039         CSIPExSIPEngine* self = new( ELeave ) CSIPExSIPEngine();
00040         CleanupStack::PushL( self );
00041         self->ConstructL( aAppUid, aObserver );
00042         CleanupStack::Pop( self );
00043         
00044         return self;
00045         }
00046 
00047 
00048 // -----------------------------------------------------------------------------
00049 // Destructor.
00050 // -----------------------------------------------------------------------------
00051 CSIPExSIPEngine::~CSIPExSIPEngine()
00052         {
00053         SdpCodecStringPool::Close();
00054         
00055         delete iIdle;
00056         delete iClientEstablishing;
00057         delete iClientOffering;
00058         delete iServerOffering;
00059         delete iServerEstablishing;
00060         delete iEstablished;
00061         delete iTerminating;
00062 
00063         delete iClientTx;
00064         delete iServerTx;
00065 
00066         delete iDialogAssoc;
00067 
00068         delete iConnection;
00069         delete iProfile;
00070         delete iProfileRegistry;
00071         delete iSIP;
00072         }
00073 
00074 
00075 // -----------------------------------------------------------------------------
00076 // CSIPExSIPEngine::CSIPExSIPEngine
00077 // C++ default constructor.
00078 // -----------------------------------------------------------------------------
00079 CSIPExSIPEngine::CSIPExSIPEngine()
00080         {
00081         }
00082 
00083 
00084 // -----------------------------------------------------------------------------
00085 // CSIPExSIPEngine::ConstructL
00086 // Symbian 2nd phase constructor. Can leave.
00087 // -----------------------------------------------------------------------------
00088 void CSIPExSIPEngine::ConstructL( 
00089     TUid aAppUid,
00090         MSIPExSIPEngineObserver* aObserver )
00091         {
00092         // Make note of the observer class.
00093         iObserver = aObserver;
00094 
00095         // Create instances of the CSIP and Profile Registry classes
00096         iSIP = CSIP::NewL( aAppUid, *this );
00097         iProfileRegistry = CSIPProfileRegistry::NewL( *iSIP, *this );
00098 
00099         // Open SDP Codec String Pool
00100         StringPoolL();
00101 
00102         // Set our local address
00103         const TUint32 KInetAddr = INET_ADDR(127,0,0,1);
00104         iLocalAddr.SetAddress( KInetAddr );
00105 
00106         // Set up the state machine
00107         // Create instances of the state classes.
00108         iIdle = CSIPExSIPIdleState::NewL();
00109         iClientEstablishing = CSIPExSIPClientEstablishingState::NewL();
00110         iClientOffering = CSIPExSIPClientOfferingState::NewL();
00111         iServerOffering = CSIPExSIPServerOfferingState::NewL();
00112         iServerEstablishing = CSIPExSIPServerEstablishingState::NewL();
00113         iEstablished = CSIPExSIPEstablishedState::NewL();
00114         iTerminating = CSIPExSIPTerminatingState::NewL();
00115 
00116         // Create the links for state transitions.
00117         iIdle->LinkStates( *iClientEstablishing, *iServerOffering );
00118         iClientEstablishing->LinkStates( *iIdle, *iClientOffering, *iEstablished );
00119         iClientOffering->LinkStates( *iIdle, *iEstablished, *iIdle );
00120         iServerOffering->LinkStates( *iServerEstablishing, *iIdle );
00121         iServerEstablishing->LinkStates( *iEstablished, *iIdle );
00122         iEstablished->LinkStates( *iTerminating, *iIdle );
00123         iTerminating->LinkStates( *iIdle );
00124 
00125         // Set current state data
00126         iCurrentState = iIdle;
00127         iConnState = CSIPConnection::EInactive;
00128         }
00129 
00130 
00131 // -----------------------------------------------------------------------------
00132 // CSIPExSIPEngine::EnableProfileL
00133 // First get the default profile from the registry, then, if it is
00134 // an IETF profile, enable it.
00135 // If non-IETF profile is default, call error callback with KErrNotSupported
00136 // and leave
00137 // Not part of the state machine.
00138 // -----------------------------------------------------------------------------
00139 EXPORT_C TBool CSIPExSIPEngine::EnableProfileL()
00140         {
00141         // Check for existing profile
00142         if ( iProfile )
00143                 {
00144                 delete iProfile;
00145                 iProfile = NULL;
00146                 }
00147     TBool registered( EFalse );
00148     
00149     // Leaves with KErrNotFound if default profile is not found
00150         iProfile = iProfileRegistry->DefaultProfileL();
00151 
00152     // Safety check that DefaultProfile() didn't return NULL pointer.
00153     if ( !iProfile )
00154         {
00155         iObserver->ProfileError( KErrNotFound );
00156         _LIT8( KProfileError, "Profile not found. Define a profile:");
00157         iObserver->WriteLog(KProfileError());
00158                 User::Leave( KErrNotFound );
00159         }
00160     // Leaves if profile type is not EInternet
00161     else if ( iProfile->Type().iSIPProfileClass != TSIPProfileTypeInfo::EInternet )
00162                 {
00163                 delete iProfile;
00164                 iProfile = NULL;
00165                 iObserver->ProfileError( KErrNotSupported );
00166                 User::Leave( KErrNotSupported );
00167                 }
00168         else
00169                 {
00170                 const TDesC8* aor = NULL;
00171         iProfile->GetParameter( KSIPUserAor, aor );     
00172         iObserver->WriteLog( *aor );
00173                 iProfileRegistry->EnableL( *iProfile, *this );
00174                 
00175                 // check whether profile was immediately set to registered state
00176                 iProfile->GetParameter( KSIPProfileRegistered, registered );
00177                 }
00178                 
00179     return registered;
00180         }
00181                 
00182 
00183 // -----------------------------------------------------------------------------
00184 // CSIPExSIPEngine::DisableProfileL
00185 // Disable the profile given as a parameter.
00186 // Not part of the state machine.
00187 // -----------------------------------------------------------------------------
00188 EXPORT_C void CSIPExSIPEngine::DisableProfileL()
00189         {
00190         if ( iProfile )
00191                 {
00192                 iProfileRegistry->Disable( *iProfile );
00193                 delete iProfile;
00194                 iProfile = NULL;                
00195                 }
00196         }
00197 
00198 
00199 // -----------------------------------------------------------------------------
00200 // CSIPExSIPEngine::SendInviteL
00201 // Send INVITE to the remote peer given as a parameter.
00202 // -----------------------------------------------------------------------------
00203 EXPORT_C void CSIPExSIPEngine::SendInviteL( const TDesC8& aSipUri )
00204         {
00205         iCurrentState->SendInviteL( *this, aSipUri );
00206         }
00207 
00208 
00209 // -----------------------------------------------------------------------------
00210 // CSIPExSIPEngine::CancelInvite
00211 // CANCEL a previously sent INVITE.
00212 // -----------------------------------------------------------------------------
00213 EXPORT_C void CSIPExSIPEngine::CancelInviteL()
00214         {
00215         iCurrentState->CancelInviteL( *this );
00216         }
00217 
00218 
00219 // -----------------------------------------------------------------------------
00220 // CSIPExSIPEngine::AcceptInvite
00221 // Accept a received INVITE with 200 (OK).
00222 // -----------------------------------------------------------------------------
00223 EXPORT_C void CSIPExSIPEngine::AcceptInviteL(const TInetAddr& aIPAddr )
00224         {
00225         iLocalAddr = aIPAddr;
00226         iCurrentState->AcceptInviteL( *this );
00227         }
00228 
00229 
00230 // -----------------------------------------------------------------------------
00231 // CSIPExSIPEngine::DeclineInvite
00232 // Decline a received INVITE with 486 (Busy Here).
00233 // -----------------------------------------------------------------------------
00234 EXPORT_C void CSIPExSIPEngine::DeclineInviteL()
00235         {
00236         iCurrentState->DeclineInviteL( *this );
00237         }
00238 
00239 
00240 // -----------------------------------------------------------------------------
00241 // CSIPExSIPEngine::EndSession
00242 // End the dialog with BYE.
00243 // -----------------------------------------------------------------------------
00244 EXPORT_C void CSIPExSIPEngine::EndSessionL()
00245         {
00246         iCurrentState->EndSessionL( *this );
00247         }
00248 
00249 
00250 // -----------------------------------------------------------------------------
00251 // CSIPExSIPEngine::CreateIML
00252 // Create and send an Instant Message to recipient defined with parameter.
00253 // This is implemented with the MESSAGE method and is sent outside of a
00254 // dialog.
00255 // -----------------------------------------------------------------------------
00256 EXPORT_C void CSIPExSIPEngine::CreateIML( 
00257     const TDesC8& aMessage,
00258         const TDesC8& aSipUri )
00259         {
00260         _LIT8( KMediaType, "SIPEx" );   // Part of content type
00261         _LIT8( KMediaSubType, "InstantMessage" );       // Part of content type
00262 
00263         // Create the necessary elements of the IM
00264         CSIPRequestElements* reqElem = CreateReqElementsLC( aSipUri );
00265         CSIPToHeader* toHeader = CreateToHeaderLC( aSipUri );
00266         reqElem->SetToHeaderL( toHeader );
00267         CleanupStack::Pop( toHeader );
00268 
00269     // Create the From header value using info from the profile
00270     const TDesC8* aor = NULL;
00271     iProfile->GetParameter( KSIPUserAor, aor ); 
00272         __ASSERT_ALWAYS( aor && *aor != KNullDesC8, User::Leave( KErrNotFound ) );
00273 
00274     CSIPAddress* addr = CSIPAddress::DecodeL( *aor );
00275         CleanupStack::PushL( addr );
00276     CSIPFromHeader* fromHeader = CSIPFromHeader::NewL( addr );
00277         CleanupStack::Pop( addr );
00278 
00279         CleanupStack::PushL( fromHeader );
00280         reqElem->SetFromHeaderL( fromHeader );
00281         CleanupStack::Pop( fromHeader );
00282         
00283 
00284         reqElem->SetMethodL( SIPStrings::StringF( SipStrConsts::EMessage ) );
00285 
00286         // Get reference to the message elements from the request
00287         // elements, create and insert content type header (ownership
00288         // of the content type object is transferred)
00289         CSIPMessageElements& msgElem = reqElem->MessageElements();
00290         CSIPContentTypeHeader* ct =
00291                 CSIPContentTypeHeader::NewLC( KMediaType, KMediaSubType );
00292         msgElem.SetContentL( aMessage.AllocL(), ct );
00293         CleanupStack::Pop( ct );
00294 
00295         // Get the current connection
00296         CSIPConnection& conn = ConnectionL();
00297 
00298         // Send the request using the connection (ownership of the
00299         // request elements object is transferred)
00300         CSIPClientTransaction* ctx = conn.SendRequestL( reqElem );
00301         CleanupStack::Pop( reqElem );
00302 
00303         delete ctx;
00304         }
00305         
00306 
00307 // -----------------------------------------------------------------------------
00308 // CSIPExSIPEngine::IMReceivedL
00309 // An Instant Message is received from the network. Respond with 200 (OK)
00310 // and alert the Engine Observer.
00311 // -----------------------------------------------------------------------------
00312 void CSIPExSIPEngine::IMReceivedL( CSIPServerTransaction* aTransaction  )
00313         {
00314         const CSIPRequestElements* reqElem = aTransaction->RequestElements();
00315         const CSIPFromHeader* fromHeader = reqElem->FromHeader();
00316         
00317     CSIPResponseElements* respElem =
00318         CSIPResponseElements::NewLC( 200, 
00319             SIPStrings::StringF( SipStrConsts::EPhraseOk ) );
00320         // Use the transaction to send 200 (OK)
00321         aTransaction->SendResponseL( respElem );
00322         CleanupStack::Pop( respElem );
00323 
00324         // Inform the observer of the Instant Message
00325         iObserver->IMReceived(
00326             fromHeader->SIPAddress().Uri8().Uri().Extract( EUriUserinfo ),
00327                 reqElem->MessageElements().Content());  
00328 
00329         // We no longer need aTransaction. Just delete it.
00330         delete aTransaction;
00331         aTransaction = NULL;
00332         }
00333         
00334 
00335 // -----------------------------------------------------------------------------
00336 // CSIPExSIPEngine::IMReceived
00337 // Call the IMReceivedL method, trapping the possible errors.
00338 // -----------------------------------------------------------------------------
00339 void CSIPExSIPEngine::IMReceived( CSIPServerTransaction* aTransaction  )
00340         {
00341         TRAPD( err, IMReceivedL( aTransaction ));
00342 
00343         if ( err != KErrNone )
00344                 {
00345                 iObserver->EngineError( err );
00346                 }
00347         }
00348         
00349 
00350 // -----------------------------------------------------------------------------
00351 // CSIPExSIPEngine::SetCurrentState
00352 // Sets the new current state of the state machine.
00353 // -----------------------------------------------------------------------------
00354 void CSIPExSIPEngine::SetCurrentState( CSIPExSIPStateBase* aState )
00355         {
00356         iCurrentState = aState;
00357         }
00358         
00359 
00360 // -----------------------------------------------------------------------------
00361 // CSIPExSIPEngine::ConnectionL
00362 // Returns the active connection.
00363 // -----------------------------------------------------------------------------
00364 CSIPConnection& CSIPExSIPEngine::ConnectionL()
00365         {
00366         CSIPConnection* conn = CurrentConnection();
00367         if ( !conn )
00368                 {
00369                 TUint32 iapId( 0 );
00370             User::LeaveIfError( iProfile->GetParameter( KSIPAccessPointId, iapId ) );
00371                 iConnection = CSIPConnection::NewL( *iSIP, iapId, *this );
00372                 return *iConnection;
00373                 }
00374         return *conn;
00375         }
00376         
00377 
00378 // -----------------------------------------------------------------------------
00379 // CSIPExSIPEngine::Profile
00380 // Returns the enabled profile.
00381 // -----------------------------------------------------------------------------
00382 CSIPProfile& CSIPExSIPEngine::Profile()
00383         {
00384         return *iProfile;
00385         }
00386         
00387 
00388 // -----------------------------------------------------------------------------
00389 // CSIPExSIPEngine::SetServerTx
00390 // Sets the current Server Transaction.
00391 // -----------------------------------------------------------------------------
00392 void CSIPExSIPEngine::SetServerTx( CSIPServerTransaction* aTx )
00393         {
00394         delete iServerTx;
00395         iServerTx = aTx;
00396         }
00397         
00398 
00399 // -----------------------------------------------------------------------------
00400 // CSIPExSIPEngine::ServerTx
00401 // Returns the current Server Transaction.
00402 // -----------------------------------------------------------------------------
00403 CSIPServerTransaction& CSIPExSIPEngine::ServerTx()
00404         {
00405         return *iServerTx;
00406         }
00407 
00408 
00409 // -----------------------------------------------------------------------------
00410 // CSIPExSIPEngine::SetClientTx
00411 // Sets the current Client Transaction.
00412 // -----------------------------------------------------------------------------
00413 void CSIPExSIPEngine::SetClientTx( CSIPClientTransaction* aTx )
00414         {
00415         delete iClientTx;
00416         iClientTx = aTx;
00417         }
00418         
00419 
00420 // -----------------------------------------------------------------------------
00421 // CSIPExSIPEngine::ClearClientTx
00422 // Deletes the current Client Transaction.
00423 // -----------------------------------------------------------------------------
00424 void CSIPExSIPEngine::ClearClientTx()
00425         {
00426         delete iClientTx;
00427         iClientTx = NULL;
00428         }
00429 
00430 
00431 // -----------------------------------------------------------------------------
00432 // CSIPExSIPEngine::ClientTx
00433 // Returns the current Client Transaction.
00434 // -----------------------------------------------------------------------------
00435 CSIPClientTransaction& CSIPExSIPEngine::ClientTx()
00436         {
00437         return *iClientTx;
00438         }
00439 
00440 
00441 // -----------------------------------------------------------------------------
00442 // CSIPExSIPEngine::SetDialogAssoc
00443 // Sets the current Invite Dialog Association.
00444 // -----------------------------------------------------------------------------
00445 void CSIPExSIPEngine::SetDialogAssoc( CSIPInviteDialogAssoc& aAssoc )
00446         {
00447         delete iDialogAssoc;
00448         iDialogAssoc = &aAssoc;
00449         }
00450 
00451 
00452 // -----------------------------------------------------------------------------
00453 // CSIPExSIPEngine::DialogAssoc
00454 // Returns the current Invite Dialog Association.
00455 // -----------------------------------------------------------------------------
00456 CSIPInviteDialogAssoc& CSIPExSIPEngine::DialogAssoc()
00457         {
00458         return *iDialogAssoc;
00459         }
00460 
00461 
00462 // -----------------------------------------------------------------------------
00463 // CSIPExSIPEngine::CreateToHeaderLC
00464 // (other items were commented in a header).
00465 // -----------------------------------------------------------------------------
00466 CSIPToHeader* CSIPExSIPEngine::CreateToHeaderLC( const TDesC8& aSipUri )
00467         {
00468         CSIPAddress* addr = CSIPAddress::DecodeL( aSipUri );
00469         CleanupStack::PushL( addr );
00470         
00471         CSIPToHeader* to = CSIPToHeader::NewL( addr );
00472         CleanupStack::Pop( addr );
00473         CleanupStack::PushL( to );
00474 
00475         return to;
00476         }
00477 
00478 
00479 // -----------------------------------------------------------------------------
00480 // CSIPExSIPEngine::CreateReqElementsLC
00481 // (other items were commented in a header).
00482 // -----------------------------------------------------------------------------        
00483 CSIPRequestElements* CSIPExSIPEngine::CreateReqElementsLC( const TDesC8& aSipUri )
00484     {
00485     CUri8* uri8 = ConvertToUri8LC( aSipUri );
00486     CSIPRequestElements* req = CSIPRequestElements::NewL( uri8 );
00487     CleanupStack::Pop( uri8 );
00488     CleanupStack::PushL( req );
00489     return req;
00490     }
00491 
00492 
00493 // -----------------------------------------------------------------------------
00494 // CSIPExSIPEngine::CreateMessageElementsLC
00495 // Create a CSIPMEssageElements instance with the required information.
00496 // -----------------------------------------------------------------------------
00497 CSIPMessageElements* CSIPExSIPEngine::CreateMessageElementsLC()
00498         {
00499         _LIT8( KMediaType, "application" );
00500         _LIT8( KMediaSubType, "sdp" );
00501 
00502         CSIPMessageElements* msgElements = CSIPMessageElements::NewLC();
00503 
00504         CSdpDocument* sdpDocument = SdpDocumentLC();
00505         MediaFieldsL( sdpDocument );
00506 
00507     HBufC8* content = SdpBodyL( sdpDocument );
00508     CleanupStack::PushL( content );
00509 
00510         CSIPContentTypeHeader* ct =
00511                 CSIPContentTypeHeader::NewLC( KMediaType, KMediaSubType );
00512 
00513         msgElements->SetContentL( content, ct );
00514 
00515         CleanupStack::Pop( ct );
00516         CleanupStack::Pop( content );
00517         CleanupStack::PopAndDestroy( sdpDocument );
00518 
00519         return msgElements;
00520         }
00521 
00522 
00523 // -----------------------------------------------------------------------------
00524 // CSIPExSIPEngine::ConvertToUri8LC
00525 // (other items were commented in a header).
00526 // -----------------------------------------------------------------------------  
00527 CUri8* CSIPExSIPEngine::ConvertToUri8LC( const TDesC8& aSipUri )
00528     {
00529     TUriParser8 parser;
00530     User::LeaveIfError( parser.Parse( aSipUri ) ); 
00531     CUri8* uri8 = CUri8::NewLC( parser );
00532     return uri8; 
00533     }
00534 
00535 
00536 // -----------------------------------------------------------------------------
00537 // CSIPExSIPEngine::SessionId
00538 // Set the session ID using a random number if not set before. Return ID.
00539 // -----------------------------------------------------------------------------
00540 TInt64 CSIPExSIPEngine::SessionId()
00541         {
00542         if ( iSessionId > 0 )
00543                 {
00544                 return iSessionId;
00545                 }
00546         else
00547                 {
00548                 // Create a random number as the session ID
00549                 TTime now;
00550                 now.HomeTime();
00551                 TInt64 seed = now.Int64();
00552 
00553                 TInt random = Math::Rand( seed );
00554                 iSessionId = random;
00555                 return iSessionId;
00556                 }
00557         }
00558 
00559 
00560 // -----------------------------------------------------------------------------
00561 // CSIPExSIPEngine::SdpDocumentLC
00562 // Create an instance of the SDP Document class, set the required fields, and
00563 // leave it on the cleanup stack. Return pointer to the SDP Document instance.
00564 // Ownership is transferred.
00565 // -----------------------------------------------------------------------------
00566 CSdpDocument* CSIPExSIPEngine::SdpDocumentLC()
00567         {
00568         _LIT8( KSessionName, "SIP Example Application" );
00569 
00570         // Create SDP document
00571         CSdpDocument* sdpDocument = CSdpDocument::NewL();
00572         CleanupStack::PushL( sdpDocument );
00573 
00574         CSdpOriginField* orgField = CSdpOriginField::NewL( KSdpNoInfoDesC8(), 
00575                                                                                                            SessionId(), 0,
00576                                                                                                            iLocalAddr );
00577         sdpDocument->SetOriginField( orgField );
00578 
00579         // Set session name
00580         sdpDocument->SetSessionNameL( KSessionName );
00581 
00582         // Set connection data
00583         CSdpConnectionField* connField = CSdpConnectionField::NewL( iLocalAddr );
00584         sdpDocument->SetConnectionField( connField );
00585 
00586         return sdpDocument;
00587         }
00588 
00589 
00590 // -----------------------------------------------------------------------------
00591 // CSIPExSIPEngine::MediaFieldsL()
00592 // Insert the media line to the SDP document given as parameter.
00593 // The format of the media line is:
00594 //     application 0 TCP SIPEx
00595 // -----------------------------------------------------------------------------
00596 void CSIPExSIPEngine::MediaFieldsL( CSdpDocument* aDocument )
00597         {
00598         _LIT8( KFormat, "SIPEx" );
00599 
00600         // Set media field
00601         // Set media type: application
00602         RStringF media = StringPoolL().StringF( SdpCodecStringConstants::EMediaApplication, 
00603                                                                 SdpCodecStringPool::StringTableL() );
00604         // Set media transport: TCP
00605         RStringF prot = StringPoolL().StringF( SdpCodecStringConstants::EProtocolTcp,
00606                                                            SdpCodecStringPool::StringTableL() );
00607         // Create the media line
00608         CSdpMediaField* mediaDescription =
00609                 CSdpMediaField::NewL( media, 0, prot, KFormat );
00610 
00611         aDocument->MediaFields().Append( mediaDescription );
00612         }
00613 
00614 
00615 // -----------------------------------------------------------------------------
00616 // CSIPExSIPEngine::SdpBodyL()
00617 // Return SDP message body in textual form.
00618 // Ownership is transferred.
00619 // -----------------------------------------------------------------------------
00620 HBufC8* CSIPExSIPEngine::SdpBodyL( CSdpDocument* aDocument )
00621         {
00622         HBufC8* sdpBuf = NULL;
00623 
00624         // Build the message body using buffer writer
00625         if ( aDocument->IsValid() )
00626                 {
00627                 CBufFlat* enBuf = CBufFlat::NewL( 1000 );
00628                 CleanupStack::PushL( enBuf );
00629                 RBufWriteStream writeStream;
00630                 writeStream.Open( *enBuf, 0 );
00631                 aDocument->EncodeL( writeStream );
00632                 writeStream.Close();
00633                 TPtr8 ptr = enBuf->Ptr( 0 );
00634                 sdpBuf = ptr.AllocL();
00635                 CleanupStack::PopAndDestroy( enBuf );
00636                 writeStream.Close();
00637                 }
00638 
00639         return sdpBuf;
00640         }
00641 
00642 
00643 // -----------------------------------------------------------------------------
00644 // CSIPExSIPEngine::CurrentConnection
00645 // (other items were commented in a header).
00646 // -----------------------------------------------------------------------------
00647 CSIPConnection* CSIPExSIPEngine::CurrentConnection()
00648     {
00649     if ( iConnection )
00650         {
00651         return iConnection;
00652         }
00653         
00654     return 0;
00655     }
00656 
00657 
00658 // -----------------------------------------------------------------------------
00659 // CSIPExSIPEngine::IPAddressFromResponseElementsL
00660 // (other items were commented in a header).
00661 // -----------------------------------------------------------------------------
00662 const TInetAddr CSIPExSIPEngine::IPAddressFromResponseElementsL(
00663         const CSIPResponseElements& aRespElem )
00664         {
00665         ;
00666         // First, retrieve remote party IP Address
00667         // Get Message Elements from Response Elements
00668         const CSIPMessageElements& msgElem = aRespElem.MessageElements();
00669 
00670         // Get message content from Message Elements
00671         const TDesC8& content = msgElem.Content();
00672 
00673         // Get the SDP Document from the message content                
00674         CSdpDocument* SDPDoc = CSdpDocument::DecodeLC( content );
00675 
00676         // Get the Connection Field from the SDP Document
00677         CSdpConnectionField* connField = SDPDoc->ConnectionField();
00678 
00679         // And, finally, get the IP Address from the Connection Field
00680         const TInetAddr* addr = connField->InetAddress();
00681         const TInetAddr inetAddr = *addr;
00682 
00683         CleanupStack::PopAndDestroy( SDPDoc );
00684 
00685         return inetAddr;
00686         }
00687 
00688 
00689 // -----------------------------------------------------------------------------
00690 // CSIPExSIPEngine::StringPoolL
00691 // Get SDP codec string pool. Open string pool if not opened.
00692 // -----------------------------------------------------------------------------
00693 RStringPool CSIPExSIPEngine::StringPoolL()
00694         {
00695         TRAPD( error, SdpCodecStringPool::OpenL() );
00696         if ( error == KErrAlreadyExists )
00697                 {
00698                 return SdpCodecStringPool::StringPoolL();
00699                 }
00700         else if ( error == KErrNone )
00701                 {
00702                 //Add missing string to the pool then return it
00703                 return SdpCodecStringPool::StringPoolL();
00704                 }
00705         else
00706                 {
00707                 User::Leave( error );
00708                 return SdpCodecStringPool::StringPoolL(); //Return here to omit warning
00709                 }
00710         }
00711 
00712 
00713 // -----------------------------------------------------------------------------
00714 // CSIPExSIPEngine::Observer
00715 // Return pointer to the class registered as Engine Observer.
00716 // -----------------------------------------------------------------------------
00717 MSIPExSIPEngineObserver* CSIPExSIPEngine::Observer()
00718         {
00719         return iObserver;
00720         }
00721 
00722 
00723 
00724 
00725 //
00726 // IMPLEMENTATION OF THE METHODS INHERITED FROM BASE CLASSES
00727 //
00728 
00729 // From MSIPObserver:
00730 
00731 // -----------------------------------------------------------------------------
00732 // CSIPExSIPEngine::IncomingRequest
00733 // Handle a request coming outside of a SIP dialog.
00734 // We have to use TRAPs because this is a non-leaving method.
00735 // We get the ownership to aTransaction.
00736 // -----------------------------------------------------------------------------
00737 void CSIPExSIPEngine::IncomingRequest( 
00738     TUint32 aIapId,
00739         CSIPServerTransaction* aTransaction )
00740         {
00741         if ( !iProfile )
00742                 {
00743                 TRAPD( err, EnableProfileL() );
00744 
00745                 if ( err != KErrNone )
00746                         {
00747                         // A profile error occured.
00748                         // Delete aTransaction and inform the observer.
00749                         delete aTransaction;
00750                         aTransaction = NULL;
00751 
00752                         iObserver->ProfileError( err );
00753                         return;
00754                         }
00755                 }
00756         
00757         if ( !CurrentConnection() )
00758                 {
00759                 // Create an instance of the SIP Connection object.
00760                 TRAPD( err2, iConnection = CSIPConnection::NewL( *iSIP, aIapId, *this ) );
00761 
00762                 if ( err2 != KErrNone )
00763                         {
00764                         // An error occured opening the connection.
00765                         // Delete aTransaction and inform the observer.
00766                         delete aTransaction;
00767                         aTransaction = NULL;
00768 
00769                         iObserver->EngineError( err2 );
00770                         return;
00771                         }
00772                 } 
00773 
00774         if ( aTransaction->Type() == SIPStrings::StringF( SipStrConsts::EInvite ) )
00775                 {
00776                 // An INVITE has been received.
00777                 // Save the pointer for later queries and eventual
00778                 // deletion.
00779                 SetServerTx(aTransaction);
00780 
00781                 // Let the current state handle the received INVITE.
00782                 // Ownership of aTransaction is transferred.
00783                 TRAPD( err2, iCurrentState->InviteReceivedL( *this, aTransaction ) );
00784                 if ( err2 != KErrNone )
00785                         {
00786                         // An error occured when handling invitation.
00787                         // Delete aTransaction and inform the observer.
00788                         delete aTransaction;
00789                         iServerTx = NULL;
00790                         iObserver->EngineError( err2 );
00791                         return;
00792                         }
00793                 }
00794         else if ( aTransaction->Type() == SIPStrings::StringF( SipStrConsts::EMessage ) )
00795                 {
00796                 IMReceived( aTransaction );
00797                 }
00798         }
00799 
00800 
00801 // -----------------------------------------------------------------------------
00802 // CSIPExSIPEngine::TimedOut - No implementation needed
00803 // -----------------------------------------------------------------------------
00804 void CSIPExSIPEngine::TimedOut(
00805         CSIPServerTransaction& /* aSIPServerTransaction */ )
00806         {
00807         }
00808 
00809 
00810 // From MSIPConnectionObserver:
00811 
00812 // -----------------------------------------------------------------------------
00813 // CSIPExSIPEngine::IncomingRequest
00814 // No dialog has been established yet, so this should be an INVITE or MESSAGE.
00815 // The ownership of aTransaction is transferred.
00816 // -----------------------------------------------------------------------------
00817 void CSIPExSIPEngine::IncomingRequest( CSIPServerTransaction* aTransaction )
00818         {
00819     if ( aTransaction->Type() == SIPStrings::StringF( SipStrConsts::EInvite ) )
00820         {
00821                 // An INVITE has been received.
00822                 // Get profile, create connection, and let the
00823                 // state machine handle it.
00824 
00825                 if ( !iProfile )
00826                         {
00827                         // If the default profile isn't enabled, do it now
00828                         TRAPD( err, EnableProfileL() );
00829 
00830                         if ( err != KErrNone )
00831                                 {
00832                                 // A profile error occured.
00833                                 // Delete aTransaction and inform the observer.
00834                                 delete aTransaction;
00835                                 aTransaction = NULL;
00836 
00837                                 iObserver->ProfileError( err );
00838                                 }
00839                         }
00840 
00841                 // The transaction still exists, which means there
00842                 // was no trouble with the profile part. Go on with
00843                 // request handling.
00844                 if ( aTransaction )
00845                         {
00846                         // The ownership of aTransaction is transferred.
00847                         // Save the pointer for later queries and eventual
00848                         // deletion.
00849                         SetServerTx(aTransaction);
00850 
00851                         // Handle the incoming request in the state machine classes
00852                         // The ownership of aTransaction is transferred.
00853                         TRAPD( err2, iCurrentState->InviteReceivedL( *this, aTransaction ));
00854                         }
00855         }
00856     else if ( aTransaction->Type() == SIPStrings::StringF( SipStrConsts::EMessage ) )
00857         {
00858         // An Instant Message is received
00859                 // The state machine isn't needed for this.
00860         IMReceived( aTransaction );
00861         }
00862         }
00863 
00864 
00865 // -----------------------------------------------------------------------------
00866 // CSIPExSIPEngine::IncomingRequest
00867 // A request concerning an established dialog is received.
00868 // -----------------------------------------------------------------------------
00869 void CSIPExSIPEngine::IncomingRequest( 
00870     CSIPServerTransaction* aTransaction,
00871         CSIPDialog& aDialog )
00872         {
00873         const RPointerArray<CSIPDialogAssocBase>& dialogAssoc =
00874         aDialog.SIPDialogAssociations();
00875 
00876         for ( TInt i = 0; i < dialogAssoc.Count(); i++ )
00877                 {
00878                 if ( dialogAssoc[i]->Type() == 
00879                     SIPStrings::StringF( SipStrConsts::EInvite ) )
00880                         {
00881                         iDialogAssoc = 
00882                             reinterpret_cast<CSIPInviteDialogAssoc*>( dialogAssoc[0] );
00883                         break;
00884                         }
00885                 }
00886 
00887     if ( aTransaction->Type() == SIPStrings::StringF( SipStrConsts::EBye ) )
00888         {
00889                 // The ownership of aTransaction is transferred.
00890                 // Save the pointer for later queries and eventual
00891                 // deletion.
00892                 SetServerTx(aTransaction);
00893 
00894         TRAPD( err, iCurrentState->ByeReceivedL( *this, *aTransaction ) );
00895 
00896         if ( err != KErrNone )
00897                 {
00898                 iObserver->EngineError( err );
00899                 }
00900         }
00901     else if ( aTransaction->Type() == 
00902         SIPStrings::StringF( SipStrConsts::EAck ) )
00903         {
00904                 // The ownership of aTransaction is transferred.
00905                 // Save the pointer for later queries and eventual
00906                 // deletion.
00907                 SetServerTx(aTransaction);
00908 
00909         TRAPD( err, iCurrentState->AckReceivedL( *this, *aTransaction ) );
00910 
00911         if ( err != KErrNone )
00912                 {
00913                 iObserver->EngineError( err );
00914                 }
00915         }
00916     else if ( aTransaction->Type() == 
00917         SIPStrings::StringF( SipStrConsts::EMessage ) )
00918         {
00919         IMReceived( aTransaction );
00920         }
00921     else
00922         {
00923         // Unknown, or unimplemented, request received
00924                 delete aTransaction;
00925                 aTransaction = NULL;
00926         iObserver->EngineError( KErrNotSupported );
00927         }
00928         }
00929 
00930 // -----------------------------------------------------------------------------
00931 // CSIPExSIPEngine::IncomingResponse - No implementation needed
00932 // -----------------------------------------------------------------------------
00933 void CSIPExSIPEngine::IncomingResponse( 
00934     CSIPClientTransaction& /* aTransaction */ )
00935         {
00936         }
00937 
00938 
00939 // -----------------------------------------------------------------------------
00940 // CSIPExSIPEngine::IncomingResponse
00941 // A response inside an established dialog is received.
00942 // -----------------------------------------------------------------------------
00943 void CSIPExSIPEngine::IncomingResponse( CSIPClientTransaction& aTransaction,
00944                                                                                 CSIPDialogAssocBase& aDialogAssoc )
00945         {
00946         if ( aDialogAssoc.Type() == SIPStrings::StringF( SipStrConsts::EInvite )  )
00947                 {
00948                 iDialogAssoc = reinterpret_cast<CSIPInviteDialogAssoc*>( &aDialogAssoc );
00949                 }
00950         
00951         TRAPD( err, iCurrentState->ResponseReceivedL( *this, aTransaction ) );
00952         
00953         if ( err != KErrNone )
00954                 {
00955                 iObserver->EngineError( err );
00956                 }
00957         }
00958 
00959 
00960 // -----------------------------------------------------------------------------
00961 // CSIPExSIPEngine::IncomingResponse
00962 // Since the ownership is transferred, aDialogAssoc needs to be deleted
00963 // -----------------------------------------------------------------------------
00964 void CSIPExSIPEngine::IncomingResponse( 
00965     CSIPClientTransaction& /* aTransaction */,
00966         CSIPInviteDialogAssoc* aDialogAssoc )
00967         {
00968         delete aDialogAssoc;
00969         aDialogAssoc = NULL;
00970         }
00971 
00972 
00973 // -----------------------------------------------------------------------------
00974 // CSIPExSIPEngine::IncomingResponse - No implementation needed
00975 // -----------------------------------------------------------------------------
00976 void CSIPExSIPEngine::IncomingResponse( 
00977     CSIPClientTransaction& /* aTransaction */,
00978         CSIPRegistrationBinding& /* aRegistration */ )
00979         {
00980         
00981         }
00982 
00983 
00984 // -----------------------------------------------------------------------------
00985 // CSIPExSIPEngine::ErrorOccured
00986 // (other items were commented in a header).
00987 // -----------------------------------------------------------------------------
00988 void CSIPExSIPEngine::ErrorOccured( 
00989     TInt /* aError */,
00990         CSIPTransactionBase& /* aTransaction */ )
00991         {
00992         
00993         }
00994 
00995 
00996 // -----------------------------------------------------------------------------
00997 // CSIPExSIPEngine::ErrorOccured
00998 // (other items were commented in a header).
00999 // -----------------------------------------------------------------------------
01000 void CSIPExSIPEngine::ErrorOccured( 
01001     TInt /* aError */,
01002         CSIPClientTransaction& /* aTransaction */,
01003         CSIPRegistrationBinding& /* aRegistration */ )
01004         {
01005         
01006         }
01007 
01008 
01009 // -----------------------------------------------------------------------------
01010 // CSIPExSIPEngine::ErrorOccured
01011 // (other items were commented in a header).
01012 // -----------------------------------------------------------------------------
01013 void CSIPExSIPEngine::ErrorOccured( 
01014     TInt /* aError */,
01015         CSIPTransactionBase& /* aTransaction */,
01016         CSIPDialogAssocBase& /* aDialogAssoc */ )
01017         {
01018         
01019         }
01020 
01021 
01022 // -----------------------------------------------------------------------------
01023 // CSIPExSIPEngine::ErrorOccured
01024 // (other items were commented in a header).
01025 // -----------------------------------------------------------------------------
01026 void CSIPExSIPEngine::ErrorOccured( 
01027     TInt /* aError */, 
01028     CSIPRefresh& /* aSIPRefresh */ )
01029         {
01030         
01031         }
01032 
01033 
01034 // -----------------------------------------------------------------------------
01035 // CSIPExSIPEngine::ErrorOccured
01036 // (other items were commented in a header).
01037 // -----------------------------------------------------------------------------
01038 void CSIPExSIPEngine::ErrorOccured( 
01039     TInt /* aError */,
01040         CSIPRegistrationBinding& /* aRegistration */ )
01041         {
01042         
01043         }
01044 
01045 
01046 // -----------------------------------------------------------------------------
01047 // CSIPExSIPEngine::ErrorOccured
01048 // (other items were commented in a header).
01049 // -----------------------------------------------------------------------------
01050 void CSIPExSIPEngine::ErrorOccured( 
01051     TInt /* aError */,
01052         CSIPDialogAssocBase& /* aDialogAssoc */ )
01053         {
01054         
01055         }
01056 
01057 
01058 // -----------------------------------------------------------------------------
01059 // CSIPExSIPEngine::InviteCompleted
01060 // (other items were commented in a header).
01061 // -----------------------------------------------------------------------------
01062 void CSIPExSIPEngine::InviteCompleted( 
01063     CSIPClientTransaction& /* aTransaction */ )
01064         {
01065         delete iClientTx;
01066         iClientTx = NULL;
01067         }
01068 
01069 // -----------------------------------------------------------------------------
01070 // CSIPExSIPEngine::InviteCanceled
01071 // (other items were commented in a header).
01072 // -----------------------------------------------------------------------------
01073 void CSIPExSIPEngine::InviteCanceled( 
01074     CSIPServerTransaction& /* aTransaction */ )
01075     {
01076     delete iClientTx; 
01077         iClientTx = NULL;
01078     }
01079 
01080 // -----------------------------------------------------------------------------
01081 // CSIPExSIPEngine::ConnectionStateChanged
01082 // (other items were commented in a header).
01083 // -----------------------------------------------------------------------------
01084 void CSIPExSIPEngine::ConnectionStateChanged( CSIPConnection::TState aState )
01085         {
01086         if ( iConnState == CSIPConnection::EActive &&
01087                  aState != CSIPConnection::EActive )
01088                 {
01089                 // A previously active connection is active no more
01090                 iObserver->ConnectionLost();
01091                 }
01092         else
01093                 {
01094                 iConnState = aState;
01095                 }
01096         }
01097 
01098 
01099 
01100 // From MSIPProfileRegistryObserver
01101 
01102 
01103 // -----------------------------------------------------------------------------
01104 // CSIPExSIPEngine::ProfileRegistryErrorOccurred
01105 // (other items were commented in a header).
01106 // -----------------------------------------------------------------------------
01107 void CSIPExSIPEngine::ProfileRegistryEventOccurred( 
01108     TUint32 aProfileId, 
01109     TEvent aEvent )
01110     {
01111     switch (aEvent)
01112             {
01113             case MSIPProfileRegistryObserver::EProfileRegistered:
01114                 {
01115                 HandleProfileRegistered( aProfileId );
01116                 break;
01117                 }
01118             case MSIPProfileRegistryObserver::EProfileDeregistered:
01119                 {
01120                 HandleProfileDeregistered( aProfileId );
01121                 break;
01122                 }
01123             case MSIPProfileRegistryObserver::EProfileDestroyed:
01124                 {
01125             HandleProfileDestroyed( aProfileId );
01126                 break;
01127                 }
01128             default:
01129                 {
01130                 // MSIPProfileRegistryObserver::EProfileCreated and
01131                 // MSIPProfileRegistryObserver::EProfileUpdated
01132                 // are ignored
01133                 break;
01134                 }
01135             }
01136     }
01137 
01138 // -----------------------------------------------------------------------------
01139 // CSIPExSIPEngine::ProfileRegistryErrorOccurred
01140 // (other items were commented in a header).
01141 // -----------------------------------------------------------------------------
01142 void CSIPExSIPEngine::ProfileRegistryErrorOccurred( 
01143     TUint32 /* aSIPProfileId */,
01144         TInt aError )
01145         {
01146         iObserver->ProfileError( aError );
01147         }
01148         
01149 
01150         
01151 // Private handling for profile events
01152 
01153 // -----------------------------------------------------------------------------
01154 // CSIPExSIPEngine::HandleProfileRegistered
01155 // (other items were commented in a header).
01156 // -----------------------------------------------------------------------------
01157 void CSIPExSIPEngine::HandleProfileRegistered( TUint32 aSIPProfileId )
01158         {
01159     TUint32 profileId( 0 );
01160         iProfile->GetParameter( KSIPProfileId, profileId );
01161     if ( aSIPProfileId == profileId )
01162         {
01163                 // The profile registration is complete
01164                 // Inform the Engine Observer
01165                 iObserver->ProfileEnabled( aSIPProfileId );
01166         }
01167         }
01168         
01169 // -----------------------------------------------------------------------------
01170 // CSIPExSIPEngine::HandleProfileDeregistered
01171 // (other items were commented in a header).
01172 // -----------------------------------------------------------------------------
01173 void CSIPExSIPEngine::HandleProfileDeregistered( TUint32 aSIPProfileId )
01174         {
01175         TUint32 profileId( 0 );
01176         iProfile->GetParameter( KSIPProfileId, profileId );
01177     if ( aSIPProfileId == profileId )
01178         {
01179                 // The previously registered profile has
01180                 // become unregistered.
01181         delete iDialogAssoc;
01182         iDialogAssoc = 0;
01183         delete iConnection;
01184         iConnection = 0;
01185         //iNotOwnedConnection = 0;
01186         delete iProfile;
01187         iProfile = 0;
01188         
01189         iObserver->ProfileError( KErrGeneral );         
01190         }
01191         }
01192 
01193 // -----------------------------------------------------------------------------
01194 // CSIPExSIPEngine::HandleProfileDestroyed
01195 // (other items were commented in a header).
01196 // -----------------------------------------------------------------------------
01197 void CSIPExSIPEngine::HandleProfileDestroyed( TUint32 /* aSIPProfileId */ )
01198         {
01199         delete iDialogAssoc;
01200         iDialogAssoc = 0;
01201         delete iConnection;
01202         iConnection = 0;
01203         //iNotOwnedConnection = 0;
01204         delete iProfile;
01205         iProfile = 0;
01206 
01207         iObserver->ProfileError( KErrGeneral );
01208         }
01209         
01210 // End of file

© Nokia 2006

Back to top