omaprovisioning/provisioning/ProvisioningHandler/Src/CWPMessage.cpp
changeset 0 b497e44ab2fc
child 25 b183ec05bd8c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omaprovisioning/provisioning/ProvisioningHandler/Src/CWPMessage.cpp	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,638 @@
+/*
+* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Main class for handling provisioning message
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <biodb.h>      // BIO Message Database and message query methods
+#include <msvuids.h>    // KUidMsvMessageEntry const
+#include <biouids.h>    // KUidBioMessageTypeMtm const
+#include <msvapi.h>
+#include <msvids.h>
+#include <txtfmlyr.h>
+#include <txtrich.h>
+#include <smut.h>
+#include <smuthdr.h>
+#include <provisioninghandlerresource.rsg>
+#include <pushmessage.h>
+#include <CWPEngine.h>
+#include <WPAdapterUtil.h>
+#include <data_caging_path_literals.hrh>
+#include <centralrepository.h>
+#include <csmsgetdetdescinterface.h>
+#include "MWPPhone.h"
+#include "WPPhoneFactory.h"
+#include "CWPBootstrap.h"
+#include "CWPMessage.h"
+#include "CWPPushMessage.h"
+#include "WPHandlerDebug.h"
+#include "WPHandlerUtil.h"
+#include "ProvisioningDebug.h"
+#include "ProvisioningInternalCRKeys.h"
+
+
+// CONSTANTS
+_LIT(KResourceName, "ProvisioningHandler");
+
+_LIT(KDirAndFile,"z:ProvisioningHandler.rsc");
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CWPMessage::CWPMessage
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CWPMessage::CWPMessage()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CWPMessage::ConstructL( CPushMessage& aMessage )
+    {
+    FLOG( _L( "CWPMessage::ConstructL: Opening msg session" ) );
+
+    iSession = CMsvSession::OpenSyncL(*this);
+
+    FLOG( _L( "CWPMessage::ConstructL: Constructing push message" ) );
+    iMessage = CWPPushMessage::NewL();
+
+    TPtrC8 bodyValue;
+    TPtrC8 headerValue;
+    if (aMessage.GetMessageBody(bodyValue)
+        && aMessage.GetHeader(headerValue) )
+        {
+        iMessage->SetL( headerValue, bodyValue );
+        }
+
+    TPtrC8 serverValue;
+    if( aMessage.GetServerAddress( serverValue ) )
+        {
+        FLOG( _L( "CWPMessage::Begin originator" ) );
+        DHEX( serverValue );
+        FLOG( _L( "CWPMessage::End originator" ) );
+        iMessage->SetOriginatorL( serverValue );
+        iSender = serverValue.AllocL();
+        }
+
+    FLOG( _L( "CWPMessage::Begin header" ));
+    DHEX( iMessage->Header() );
+    FLOG( _L( "CWPMessage::Begin message body" ) );
+    DHEX( iMessage->Body() );
+    FLOG( _L( "CWPMessage::End message" ) );
+
+    FLOG( _L( "CWPMessage::ConstructL: Retrieving BIO message type" ) );
+    BioMessageTypeL( aMessage );
+
+    FLOG( _L( "CWPMessage::ConstructL: Finished" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CWPMessage* CWPMessage::NewL( CPushMessage& aMessage )
+    {
+    CWPMessage* self = new(ELeave) CWPMessage; 
+    CleanupStack::PushL(self);
+    self->ConstructL( aMessage );
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// Destructor
+CWPMessage::~CWPMessage()
+    {
+    delete iPhone;
+    delete iSession;
+    delete iSender;
+    delete iMessage;
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::HandleSessionEventL
+// -----------------------------------------------------------------------------
+//
+void CWPMessage::HandleSessionEventL(TMsvSessionEvent /*aEvent*/, 
+    TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::ProcessL
+// -----------------------------------------------------------------------------
+//
+void CWPMessage::ProcessL()
+    {
+    FLOG( _L( "CWPMessage::ProcessL: Started" ) );
+
+    // Create a phone if one does not already exist
+    if( !iPhone )
+        {
+        iPhone = WPPhoneFactory::CreateL();
+        }
+
+    FLOG( _L( "CWPMessage::ProcessL: Creating engine" ) );
+
+    // Read the message into the engine
+    CWPEngine* engine = CWPEngine::NewLC(); // on CS
+
+    FLOG( _L( "CWPMessage::ProcessL: Importing document" ) );
+    engine->ImportDocumentL( iMessage->Body() );
+
+    FLOG( _L( "CWPMessage::ProcessL: Populating adapters" ) );
+    engine->PopulateL();
+
+    FTRACE(RDebug::Print(_L(" WPMessage::ProcessL: Number of settings: (%d)"), engine->ItemCount()));
+    // Check if the sender can be trusted
+    TPtrC8 orig8( iMessage->Originator() );
+    HBufC* originator = HBufC::NewLC( orig8.Length() );
+    TPtr orig16( originator->Des() );
+    orig16.Copy( orig8 );
+    if( engine->ContextExistsL( orig16 ) )
+        {
+        iMessage->SetAuthenticated( ETrue );
+        }
+    CleanupStack::PopAndDestroy(); // originator
+    
+    // Try bootstrapping
+    FLOG( _L( "CWPMessage::ProcessL: Bootstrapping" ) );
+    CWPBootstrap* bootstrap = CWPBootstrap::NewL( iPhone->SubscriberId() );
+    CleanupStack::PushL( bootstrap );
+
+    CWPBootstrap::TBootstrapResult result( 
+        bootstrap->BootstrapL( *iMessage, *engine, KNullDesC ) );
+    CleanupStack::PopAndDestroy(); // bootstrap
+
+    FTRACE(RDebug::Print(_L(" WPMessage::ProcessL: Bootstrap result: (%d)"), result));
+        // See UI specs figure 1 
+    TBool haveSettings( engine->ItemCount() > 0 );
+    switch( result )
+        {
+        case CWPBootstrap::ENoBootstrap:
+            {
+            FLOG( _L( "CWPMessage::ProcessL: Bootstrapping ENoBootstrap" ) );
+            // If there's no bootstrap, just save the message
+            if( haveSettings )
+                {
+                StoreMsgL();
+                }
+            else
+                {
+                User::Leave( KErrCorrupt );
+                }
+            break;
+            }
+
+        case CWPBootstrap::ENotAuthenticated:
+            {
+            FLOG( _L( "CWPMessage::ProcessL: Bootstrapping ENotAuthenticated" ) );
+            if( haveSettings )
+                {
+                StoreMsgL();
+                }
+            else
+            {
+                
+            // Message is ignored and an information SMs is put to Inbox.
+            //Information SMs can be Class0,  based on operator requirement.
+            TInt auth_value;
+            CRepository * rep = 0;
+            TRAPD( err, rep = CRepository::NewL( KCRUidOMAProvisioningLV ));
+            if(err == KErrNone)
+            {
+            	rep->Get( KOMAProvAuthFailMsgHandling, auth_value );
+            	delete rep;
+            	
+            	if(auth_value == 1)
+            	StoreMsgclass0L(R_TEXT_AUTHENTICATION_FAILED);
+            	else
+            	StoreMsgL(R_TEXT_AUTHENTICATION_FAILED);
+            	
+            	User::Leave( KErrAccessDenied ); 
+            }
+            else
+            {
+            StoreMsgL(R_TEXT_AUTHENTICATION_FAILED);
+            User::Leave( KErrAccessDenied );                         
+            }
+                }
+            break;
+            }
+
+        case CWPBootstrap::EPinRequired:
+            {
+            FLOG( _L( "CWPMessage::ProcessL: Bootstrapping EPinRequired" ) );
+            
+            // If PIN is required, defer authentication to ProvisioningBC
+            if( haveSettings )
+                {
+                StoreMsgL();
+                }
+            else
+                {
+                User::Leave( KErrCorrupt );
+                }
+            break;
+            }
+
+        case CWPBootstrap::EAuthenticationFailed:
+            {
+            FLOG( _L( "CWPMessage::ProcessL: Bootstrapping EAuthenticationFailed" ) );
+            
+            // Bootstrap is ignored and an information SMS is put to Inbox.
+            //Information SMs can be Class0,  based on operator requirement.
+            TInt auth_value;
+            CRepository * rep = 0;
+            TRAPD( err, rep = CRepository::NewL( KCRUidOMAProvisioningLV ));
+            if(err == KErrNone)
+            {
+            	rep->Get( KOMAProvAuthFailMsgHandling, auth_value );
+            	delete rep;
+            	
+            	if(auth_value == 1)
+            	StoreMsgclass0L(R_TEXT_AUTHENTICATION_FAILED);
+            	else
+            	StoreMsgL(R_TEXT_AUTHENTICATION_FAILED);
+            	
+            	User::Leave( KErrAccessDenied );
+            	
+            }
+            else
+            {
+            StoreMsgL(R_TEXT_AUTHENTICATION_FAILED);
+            User::Leave( KErrAccessDenied );
+            }
+            break;
+            }
+
+        case CWPBootstrap::EBootstrapExists:
+            {
+            FLOG( _L( "CWPMessage::ProcessL: Bootstrapping EBootstrapExists" ) );
+            
+            if( haveSettings )
+                {
+                StoreMsgL();
+                }
+            else
+                {
+                // Bootstrap is ignored and an information SMS is put to Inbox
+                StoreMsgL( R_TEXT_BOOTSTRAP_EXISTS );
+                User::Leave( KErrAlreadyExists );
+                }
+            break;
+            }
+
+        case CWPBootstrap::ESucceeded:
+            {
+            FLOG( _L( "CWPMessage::ProcessL: Bootstrapping ESucceeded" ) );
+            
+            if( haveSettings )
+                {
+                StoreMsgL();
+                }
+            else
+                {
+                StoreMsgL( R_TEXT_BOOTSTRAPPED );
+                }
+            break;
+            }
+
+        default:
+            {
+            break;
+            }
+        }
+
+    CleanupStack::PopAndDestroy(); // engine
+
+    FLOG( _L( "CWPMessage::ProcessL: Finished" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::BioMessageTypeL
+// -----------------------------------------------------------------------------
+//
+void CWPMessage::BioMessageTypeL( CPushMessage& aMessage )
+    {
+    FLOG( _L( "CWPMessage::BioMessageTypeL" ) );
+    
+    // need to create local RFs for BIO otherwise raises exception
+    RFs localFS;
+    User::LeaveIfError(localFS.Connect());
+    CleanupClosePushL(localFS);
+    CBIODatabase* bioDB = CBIODatabase::NewLC(localFS);
+
+    TPtrC contentTypePtr;
+    aMessage.GetContentType(contentTypePtr);
+    
+    iBioUID = KNullUid;
+    // IsBioMessageL returns KErrNone if found or KErrNotFound if not found 
+    TInt retVal = bioDB->IsBioMessageL(EBioMsgIdIana, contentTypePtr, NULL, iBioUID);
+    FTRACE(RDebug::Print(_L(" CWPMessage::BioMessageTypeL (%d)"), retVal));
+    CleanupStack::PopAndDestroy(2); // bioDB, localFS
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::StoreMsgL
+// -----------------------------------------------------------------------------
+//
+void CWPMessage::StoreMsgL()
+    {
+    FLOG( _L( "CWPMessage::StoreMsgL" ) );
+    
+    // create an invisible blank entry 
+    TMsvEntry entry;
+    PrepareEntryLC( entry ); // details on cleanup stack
+    entry.iBioType = iBioUID.iUid;
+    entry.iMtm = KUidBIOMessageTypeMtm;
+    
+    // Look up and set the description
+    FLOG( _L( "CWPMessage::StoreMsgL 1" ) );
+    
+    TInt index;
+    CBIODatabase* bioDB = CBIODatabase::NewLC( iSession->FileSession() );
+    FLOG( _L( "CWPMessage::StoreMsgL 2" ) );
+    TRAPD( err, bioDB->GetBioIndexWithMsgIDL( iBioUID, index ) );
+    if (err ==KErrNone)
+        {
+        FLOG( _L( "CWPMessage::StoreMsgL 3" ) );
+        HBufC* description = bioDB->BifReader(index).Description().AllocL();
+        FLOG( _L( "CWPMessage::StoreMsgL 4" ) );
+        entry.iDescription.Set(*description);
+        FLOG( _L( "CWPMessage::StoreMsgL 5" ) );
+        CleanupStack::PopAndDestroy();  // bioDB
+        CleanupStack::PushL( description );
+        }
+    else
+        {
+        FTRACE(RDebug::Print(_L(" CWPMessage::StoreMsgL err (%d)"), err));
+        CleanupStack::PopAndDestroy();  // bioDB
+        }
+        
+    FLOG( _L( "CWPMessage::StoreMsgL 6" ) );
+    // Store entry in inbox
+    CMsvEntry* msvEntry = iSession->GetEntryL( KMsvGlobalInBoxIndexEntryId );
+    FLOG( _L( "CWPMessage::StoreMsgL 7" ) );
+    CleanupStack::PushL(msvEntry);
+    msvEntry->CreateL(entry);
+    msvEntry->Session().CleanupEntryPushL(entry.Id());
+    msvEntry->SetEntryL(entry.Id());
+    FLOG( _L( "CWPMessage::StoreMsgL 8" ) );
+    // Save the message
+    CMsvStore* store = msvEntry->EditStoreL();
+    CleanupStack::PushL(store);
+    FLOG( _L( "CWPMessage::StoreMsgL 9" ) );
+    iMessage->StoreL( *store );
+    store->CommitL();
+    
+    // Complete processing the message
+    PostprocessEntryL( *msvEntry, entry );
+
+    CleanupStack::PopAndDestroy(); //store
+    msvEntry->Session().CleanupEntryPop(); //entry
+    CleanupStack::PopAndDestroy(3); //description, details, msvEntry
+    FLOG( _L( "CWPMessage::StoreMsgL Done" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::StoreMsgL
+// -----------------------------------------------------------------------------
+//
+void CWPMessage::StoreMsgL( TInt aResource )
+    {
+    FLOG( _L( "CWPMessage::StoreMsgL(aResource)" ) );
+    
+    // create an invisible blank entry 
+    TMsvEntry entry;
+    PrepareEntryLC( entry ); // details on cleanup stack
+    entry.iMtm = KUidMsgTypeSMS;     
+
+    // Store entry in inbox
+    CMsvEntry* msvEntry = iSession->GetEntryL(KMsvGlobalInBoxIndexEntryId);
+    CleanupStack::PushL(msvEntry);
+    msvEntry->CreateL(entry);
+    msvEntry->Session().CleanupEntryPushL(entry.Id());
+    msvEntry->SetEntryL(entry.Id());
+
+    // Save the message body
+    CMsvStore* store = msvEntry->EditStoreL();
+    CleanupStack::PushL(store);
+    CParaFormatLayer* paraFormat = CParaFormatLayer::NewL();
+    CleanupStack::PushL( paraFormat );
+    CCharFormatLayer* charFormat = CCharFormatLayer::NewL();
+    CleanupStack::PushL( charFormat );
+    CRichText* body = CRichText::NewL( paraFormat, charFormat );
+    CleanupStack::PushL( body );
+    HBufC* text = LoadStringLC( aResource );
+    body->InsertL( body->DocumentLength(), *text );
+    store->StoreBodyTextL( *body );
+
+    // Store the actual message for post-mortem analysis
+    iMessage->StoreL( *store );
+
+    // Save the SMS header and create a description field
+    CSmsHeader* header = CSmsHeader::NewL( CSmsPDU::ESmsDeliver, *body );
+    CleanupStack::PushL( header );
+    TBuf<KSmsDescriptionLength> description;
+
+    CSmsGetDetDescInterface* smsPlugin = CSmsGetDetDescInterface::NewL();
+    CleanupStack::PushL( smsPlugin );
+    smsPlugin->GetDescription( header->Message(), description );
+    CleanupStack::PopAndDestroy( smsPlugin );
+
+    entry.iDescription.Set( description );
+    header->StoreL( *store );
+    store->CommitL();
+    CleanupStack::PopAndDestroy( 5 ); // header, text, body, charformat, paraFormat
+
+    // Complete processing the message
+    PostprocessEntryL( *msvEntry, entry );
+
+    CleanupStack::PopAndDestroy(); //store
+    msvEntry->Session().CleanupEntryPop(); //entry
+    CleanupStack::PopAndDestroy(2); //details, msvEntry
+    }
+    
+// -----------------------------------------------------------------------------
+// CWPMessage::StoreMsgclass0L
+// -----------------------------------------------------------------------------
+//
+void CWPMessage::StoreMsgclass0L( TInt aResource )
+    {
+    FLOG( _L( "CWPMessage::StoreMsgL(aResource)" ) );
+    
+    // create an invisible blank entry 
+    TMsvEntry entry;
+    PrepareEntryLC( entry ); // details on cleanup stack
+    entry.iMtm = KUidMsgTypeSMS;     
+
+    // Store entry in inbox
+    CMsvEntry* msvEntry = iSession->GetEntryL(KMsvGlobalInBoxIndexEntryId);
+    CleanupStack::PushL(msvEntry);
+    msvEntry->CreateL(entry);
+    msvEntry->Session().CleanupEntryPushL(entry.Id());
+    msvEntry->SetEntryL(entry.Id());
+
+    // Save the message body
+    CMsvStore* store = msvEntry->EditStoreL();
+    CleanupStack::PushL(store);
+    CParaFormatLayer* paraFormat = CParaFormatLayer::NewL();
+    CleanupStack::PushL( paraFormat );
+    CCharFormatLayer* charFormat = CCharFormatLayer::NewL();
+    CleanupStack::PushL( charFormat );
+    CRichText* body = CRichText::NewL( paraFormat, charFormat );
+    CleanupStack::PushL( body );
+    HBufC* text = LoadStringLC( aResource );
+    body->InsertL( body->DocumentLength(), *text );
+    store->StoreBodyTextL( *body );
+
+    // Store the actual message for post-mortem analysis
+    iMessage->StoreL( *store );
+
+    
+   
+    
+    // Save the SMS header and create a description field
+    CSmsHeader* header = CSmsHeader::NewL( CSmsPDU::ESmsDeliver, *body );
+    
+    
+    CleanupStack::PushL( header );
+    TBuf<KSmsDescriptionLength> description;
+
+    
+    //class 0 Implementation
+    CSmsMessage &msg = header->Message();
+	CSmsPDU &pdu = msg.SmsPDU(); 
+	pdu.SetClass(ETrue,TSmsDataCodingScheme::ESmsClass0);
+
+ 	CSmsGetDetDescInterface* smsPlugin = CSmsGetDetDescInterface::NewL();
+    CleanupStack::PushL( smsPlugin );
+    smsPlugin->GetDescription( msg , description );
+    CleanupStack::PopAndDestroy( smsPlugin );
+
+    entry.iDescription.Set( description );
+    header->StoreL( *store );
+    store->CommitL();
+    CleanupStack::PopAndDestroy( 5 ); // header, text, body, charformat, paraFormat
+
+    // Complete processing the message
+    PostprocessEntryL( *msvEntry, entry );
+
+    CleanupStack::PopAndDestroy(); //store
+    msvEntry->Session().CleanupEntryPop(); //entry
+    CleanupStack::PopAndDestroy(2); //details, msvEntry
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::PrepareEntry
+// -----------------------------------------------------------------------------
+//
+void CWPMessage::PrepareEntryLC( TMsvEntry& aEntry )
+    {
+    FLOG( _L( "CWPMessage::PrepareEntryLC" ) );
+    
+    // Current time
+    TTime time;
+
+	// Get Universal time
+	time.UniversalTime();
+
+	FLOG( _L( "CWPMessage::PrepareEntryLC create an invisible blank entry" ) );	
+    // create an invisible blank entry 
+    aEntry.iType = KUidMsvMessageEntry;
+    aEntry.SetVisible(EFalse);
+    aEntry.SetInPreparation(ETrue);
+    aEntry.SetReadOnly(EFalse);
+    aEntry.SetUnread(ETrue);
+    aEntry.iDate = time;
+    aEntry.iServiceId = KMsvLocalServiceIndexEntryId;
+    aEntry.iError = KErrNone;
+    // iMtmData1 is been used/reserved for count, please don't use for any other purpose.
+    aEntry.SetMtmData1(3);
+    FLOG( _L( "CWPMessage::PrepareEntryLC create an invisible blank entry done" ) );
+    // Look up the details
+    HBufC* details = NULL;
+    if( iMessage->Authenticated() )
+        {
+        FLOG( _L( "CWPMessage::PrepareEntryLC iMessage->Authenticated() true" ) );
+        details = LoadStringLC( R_FROM_SERVICEPROVIDER );
+        FLOG( _L( "CWPMessage::PrepareEntryLC LoadString done" ) );
+        }
+    else
+        {
+        FLOG( _L( "CWPMessage::PrepareEntryLC iMessage->Authenticated() false" ) );
+        if( iSender )
+            {
+            FLOG( _L( "CWPMessage::PrepareEntryLC iSender true" ) );
+            details = HBufC::NewLC( iSender->Length() );
+            details->Des().Copy( *iSender );
+            }
+        else
+            {
+            FLOG( _L( "CWPMessage::PrepareEntryLC iSender false" ) );
+            details = KNullDesC().AllocLC();
+            }
+        }
+    FLOG( _L( "CWPMessage::PrepareEntryLC iDetails.Set" ) );
+    aEntry.iDetails.Set( *details );
+    FLOG( _L( "CWPMessage::PrepareEntryLC Done" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::PostprocessEntryL
+// -----------------------------------------------------------------------------
+//
+void CWPMessage::PostprocessEntryL( CMsvEntry& aCEntry, TMsvEntry& aTEntry )
+    {
+    FLOG( _L( "CWPMessage::PostprocessEntryL" ) );
+    
+    aTEntry.SetReadOnly(EFalse);
+    aTEntry.SetVisible(ETrue);
+    aTEntry.SetInPreparation(EFalse);
+    aCEntry.ChangeL(aTEntry);
+    }
+
+// -----------------------------------------------------------------------------
+// CWPMessage::LoadStringLC
+// -----------------------------------------------------------------------------
+//
+HBufC* CWPMessage::LoadStringLC( TInt aResourceId )
+    {
+    FLOG( _L( "CWPMessage::LoadStringLC" ) );
+
+	TParse parse;
+    FLOG( _L( "CWPMessage::LoadStringLC2" ) );
+    parse.Set(KDirAndFile, &KDC_RESOURCE_FILES_DIR, NULL); 
+
+    FLOG( _L( "CWPMessage::LoadStringLC3" ) );
+    HBufC* result = WPAdapterUtil::ReadHBufCL( parse.FullName(), KResourceName, aResourceId );
+    CleanupStack::PushL( result );
+    
+    FLOG( _L( "CWPMessage::LoadStringLC done" ) );
+    
+    return result;
+    }
+
+//  End of File