diff -r 000000000000 -r b497e44ab2fc omaprovisioning/provisioning/ProvisioningHandler/Src/CWPMessage.cpp --- /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 // BIO Message Database and message query methods +#include // KUidMsvMessageEntry const +#include // KUidBioMessageTypeMtm const +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 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 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