|
S60 3rd Edition SDK for Symbian OS Example Applications Guide |
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 |