diff -r d40e813b23c0 -r 48060abbbeaf htiui/HtiServicePlugins/HtiPIMServicePlugin/src/HtiSimDirHandler.cpp --- a/htiui/HtiServicePlugins/HtiPIMServicePlugin/src/HtiSimDirHandler.cpp Thu Jul 15 18:39:46 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,530 +0,0 @@ -/* - * Copyright (c) 2009 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: Implementation of SIM card contacts handling using the new - * Virtual Phonebook API - * - */ - -// INCLUDE FILES -#include "HtiSimDirHandler.h" -#include "HtiPIMServicePlugin.h" - -#include -#include - -#include -#include -// EXTERNAL DATA STRUCTURES - -// EXTERNAL FUNCTION PROTOTYPES - -// CONSTANTS -const TInt KSimInfoResponseLength = 12; -const TInt KOneSimContactBufferSize = 512; -// MACROS -// LOCAL CONSTANTS AND MACROS -_LIT8( KErrorUnrecognizedCommand, "Unrecognized command" ); -_LIT8( KErrorInvalidParameters, "Invalid command parameters" ); -_LIT8( KErrorImportFailed, "Contact import failed" ); -_LIT8( KErrorDeleteFailed, "Failed to delete contact" ); -_LIT8( KErrorSimCardInfoFailed, "Failed to get SIM card info" ); -_LIT8( KErrorFieldNotSupported, "Field is not supported"); -_LIT8( KErrorFieldTooBig, "Filed is too long"); -//_LIT8( KErrorSimStoreOpenFailed, "Failed to open SIM contact store" ); -//_LIT8( KErrorSimStoreUnavailable, "SIM contact store unavailable" ); -//_LIT8( KErrorContactOperationFailed, "SIM contact operation failed" ); - -// MODULE DATA STRUCTURES - -// LOCAL FUNCTION PROTOTYPES - -// FORWARD DECLARATIONS - -// ============================ MEMBER FUNCTIONS =============================== - -// ----------------------------------------------------------------------------- -// CHtiSimDirHandler::NewL -// Two-phased constructor. -// ----------------------------------------------------------------------------- -CHtiSimDirHandler* CHtiSimDirHandler::NewL() - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::NewL" ); - CHtiSimDirHandler* self = new (ELeave) CHtiSimDirHandler(); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(); - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::NewL" ); - return self; - } - -// ---------------------------------------------------------------------------- -// CHtiSimDirHandler::CHtiSimDirHandler -// C++ default constructor can NOT contain any code, that -// might leave. -// ---------------------------------------------------------------------------- -CHtiSimDirHandler::CHtiSimDirHandler() : - iIsBusy(EFalse), iStoreIsOpen(EFalse) - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::CHtiSimDirHandler" ); - - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::CHtiSimDirHandler" ); - } - -// ----------------------------------------------------------------------------- -// CHtiSimDirHandler::~CHtiSimDirHandler -// Destructor. -// ----------------------------------------------------------------------------- -CHtiSimDirHandler::~CHtiSimDirHandler() - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::~CHtiSimDirHandler" ); - iEtelStore.Close(); - iEtelPhone.Close(); - iEtelServer.Close(); - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::~CHtiSimDirHandler" ); - } - -// ----------------------------------------------------------------------------- -// CHtiSimDirHandler::ConstructL -// Symbian 2nd phase constructor can leave. -// ----------------------------------------------------------------------------- -void CHtiSimDirHandler::ConstructL() - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::ConstructL" ); - - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::ConstructL" ); - } - -// ----------------------------------------------------------------------------- -// CHtiSimDirHandler::SetDispatcher -// Sets the dispatcher pointer. -// ----------------------------------------------------------------------------- - -void CHtiSimDirHandler::SetDispatcher(MHtiDispatcher* aDispatcher) - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::SetDispatcher" ); - iDispatcher = aDispatcher; - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::SetDispatcher" ); - } - -// ----------------------------------------------------------------------------- -// CHtiSimDirHandler::ProcessMessageL -// Parses the received message and calls handler functions. -// ----------------------------------------------------------------------------- -void CHtiSimDirHandler::ProcessMessageL(const TDesC8& aMessage, - THtiMessagePriority /*aPriority*/) - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::ProcessMessageL" ); - - if (iStoreIsOpen == EFalse) - { - User::LeaveIfError(iEtelServer.Connect()); - User::LeaveIfError(iEtelServer.LoadPhoneModule(KMmTsyModuleName)); - User::LeaveIfError(iEtelPhone.Open(iEtelServer, KMmTsyPhoneName)); - User::LeaveIfError(iEtelStore.Open(iEtelPhone, KETelIccAdnPhoneBook)); - HTI_LOG_TEXT( "SIM card open" ); - iStoreIsOpen = ETrue; - } - - if (iIsBusy) - { - HTI_LOG_TEXT( "HtiSimDirHandler is busy - leaving" ); - User::Leave(KErrInUse); - } - - // Will be set to EFalse in the SendOkMsgL or SendErrorMessageL methods. - iIsBusy = ETrue; - - // Zero legth of aMessage tested already in CHtiPIMServicePlugin. - // Other sanity checks must be done here. - TInt err = KErrNone; - TUint8 command = aMessage.Ptr()[0]; - switch (command) - { - case CHtiPIMServicePlugin::ESimCardInfo: - { - TRAP(err ,HandleSimCardInfoL(aMessage.Right(aMessage.Length() - 1))); - break; - } - case CHtiPIMServicePlugin::EImportSimContact: - { - TRAP(err ,HandleSimContactImportL(aMessage.Right(aMessage.Length() - 1))); - break; - } - case CHtiPIMServicePlugin::EDeleteSimContact: - { - TRAP(err ,HandleSimContactDeleteL(aMessage.Right(aMessage.Length() - 1))); - break; - } - default: - { - SendErrorMessageL(KErrArgument, KErrorUnrecognizedCommand); - return; - } - } - - if (err != KErrNone) - { - iIsBusy = EFalse; - User::Leave(err); - } - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::ProcessMessageL" ); - } - -// ----------------------------------------------------------------------------- -// CHtiSimDirHandler::IsBusy -// ----------------------------------------------------------------------------- -// -TBool CHtiSimDirHandler::IsBusy() - { - return iIsBusy; - } - -// ---------------------------------------------------------------------------- -// CHtiSimDirHandler::HandleSimCardInfoL -// Gets information about the SIM card. -// ---------------------------------------------------------------------------- -void CHtiSimDirHandler::HandleSimCardInfoL(const TDesC8& aData) - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::HandleSimCardInfoL" ); - if (aData.Length() != 0) - { - HTI_LOG_TEXT( "CHtiSimDirHandler: wrong length of data" ); - SendErrorMessageL(KErrArgument, KErrorInvalidParameters); - return; - } - - RMobilePhoneBookStore::TMobilePhoneBookInfoV5 etelStoreInfo; - RMobilePhoneBookStore::TMobilePhoneBookInfoV5Pckg etelStoreInfoPckg(etelStoreInfo); - - TRequestStatus requestStatus; - iEtelStore.GetInfo(requestStatus, (TDes8&) etelStoreInfoPckg); - User::WaitForRequest(requestStatus); - if (requestStatus.Int() != KErrNone) - { - HTI_LOG_TEXT( "CHtiSimDirHandler: Failed to get SIM card info" ); - SendErrorMessageL(requestStatus.Int(), KErrorSimCardInfoFailed); - return; - } - - // Create and send response message - TBuf8 reply; - reply.Append(etelStoreInfo.iMaxSecondNames > 0 ? etelStoreInfo.iMaxSecondNames : 0); - reply.Append(etelStoreInfo.iMaxAdditionalNumbers > 0 ? etelStoreInfo.iMaxAdditionalNumbers : 0); - reply.Append(etelStoreInfo.iMaxEmailAddr > 0 ? etelStoreInfo.iMaxEmailAddr : 0); - reply.Append(etelStoreInfo.iMaxTextLength > 0 ? etelStoreInfo.iMaxTextLength : 0); - reply.Append(etelStoreInfo.iMaxNumLength > 0 ? etelStoreInfo.iMaxNumLength : 0); - reply.Append(etelStoreInfo.iMaxTextLengthSecondName > 0 ? - etelStoreInfo.iMaxTextLengthSecondName : 0); - reply.Append(etelStoreInfo.iMaxNumLengthAdditionalNumber > 0? - etelStoreInfo.iMaxNumLengthAdditionalNumber : 0); - reply.Append(etelStoreInfo.iMaxTextLengthEmailAddr > 0 ? etelStoreInfo.iMaxTextLengthEmailAddr : 0); - reply.Append( ( TUint8* ) ( &etelStoreInfo.iTotalEntries ), 2 ); - reply.Append( ( TUint8* ) ( &etelStoreInfo.iUsedEntries ), 2 ); - SendOkMsgL(reply); - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::HandleSimCardInfoL" ); - } - -// ---------------------------------------------------------------------------- -// CHtiSimDirHandler::HandleSimContactImportL -// Imports the contact to SIM card. -// ---------------------------------------------------------------------------- -void CHtiSimDirHandler::HandleSimContactImportL(const TDesC8& aData) - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::HandleSimContactImportL" ); - - if(CheckImportMsg(aData) == EFalse) - { - return; - } - - RBuf8 buffer; - buffer.CreateL(KOneSimContactBufferSize); - CleanupClosePushL(buffer); - CPhoneBookBuffer* pbBuffer = new (ELeave) CPhoneBookBuffer(); - CleanupStack::PushL(pbBuffer); - pbBuffer->Set(&buffer); - - //add new enty tag - User::LeaveIfError(pbBuffer->AddNewEntryTag()); - - TInt offset = 0; - TInt fieldCount = aData[offset]; - offset++; - - for (TInt i = 0; i < fieldCount; i++) - { - HTI_LOG_FORMAT( "Processing field %d", i + 1 ); - - TContactFieldType type = (TContactFieldType) aData[offset]; - offset++; - TInt fieldLength = aData[offset]; - offset++; - HBufC* fieldData = HBufC::NewLC(fieldLength); - fieldData->Des().Copy(aData.Mid(offset, fieldLength)); - switch (type) - { - case ENameField: - User::LeaveIfError(pbBuffer->PutTagAndValue( - RMobilePhoneBookStore::ETagPBText, fieldData->Des())); - break; - case ESecondNameField: - User::LeaveIfError(pbBuffer->PutTagAndValue( - RMobilePhoneBookStore::ETagPBSecondName, - fieldData->Des())); - break; - case EPhoneNumberField: - User::LeaveIfError( - pbBuffer->PutTagAndValue( - RMobilePhoneBookStore::ETagPBNumber, - fieldData->Des())); - break; - case EEMailField: - User::LeaveIfError(pbBuffer->PutTagAndValue( - RMobilePhoneBookStore::ETagPBEmailAddress, - fieldData->Des())); - break; - case EAdditNumberField: - User::LeaveIfError(pbBuffer->AddNewNumberTag()); - User::LeaveIfError( - pbBuffer->PutTagAndValue( - RMobilePhoneBookStore::ETagPBNumber, - fieldData->Des())); - break; - default: - HTI_LOG_FORMAT( "Unknown field type %d", type ); - User::Leave(KErrArgument); - break; - } - CleanupStack::PopAndDestroy(); // fieldData - offset += fieldLength; - } - - // save contact into sim card - TInt index = -1; - TRequestStatus status; - //store the entry in the first free location and then return - //this location within index when it completes the request - iEtelStore.Write(status, buffer, index); - User::WaitForRequest(status); - if(status.Int() != KErrNone) - { - HTI_LOG_TEXT("Failed to add SIM contact"); - SendErrorMessageL( status.Int(), KErrorImportFailed ); - } - else - { - HTI_LOG_TEXT( "SIM contact added" ); - TBuf8<4> idBuf; - idBuf.Append( ( TUint8* ) &index, 4 ); - SendOkMsgL( idBuf ); - } - CleanupStack::PopAndDestroy(2); // buffer, pbBuffer - - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::HandleSimContactImportL" ); - } - -// ---------------------------------------------------------------------------- -// CHtiSimDirHandler::HandleSimContactDeleteL -// Creates a contact view containing the contacts to be deleted. -// ---------------------------------------------------------------------------- -void CHtiSimDirHandler::HandleSimContactDeleteL(const TDesC8& aData) - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::HandleSimContactDeleteL" ); - TInt dataLength = aData.Length(); - if ( dataLength != 0 && dataLength != 4 ) - { - HTI_LOG_TEXT( "CHtiSimDirHandler: Wrong length of data" ) - SendErrorMessageL( KErrArgument, KErrorInvalidParameters ); - return; - } - - TRequestStatus status; - if (dataLength == 0) //delete all - { - iEtelStore.DeleteAll(status); - HTI_LOG_TEXT("Delete all SIM contacts"); - } - else //delete one contact with given id - { - TInt id = aData[0] + (aData[1] << 8) + (aData[2] << 16) + (aData[3] - << 24); - HTI_LOG_FORMAT( "Delete SIM contact with id %d", id ); - iEtelStore.Delete(status, id); - } - - User::WaitForRequest(status); - if(status.Int() != KErrNone) - { - HTI_LOG_TEXT("Failed to delete contact(s)"); - SendErrorMessageL( status.Int(), KErrorDeleteFailed ); - } - else - { - HTI_LOG_TEXT("SIM contact(s) deleted"); - SendOkMsgL( KNullDesC8 ); - } - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::HandleSimContactDeleteL" ); - } - -// ---------------------------------------------------------------------------- -// CHtiSimDirHandler::CheckImportMsg -// Validates the syntax of import contact message. -// ---------------------------------------------------------------------------- -TBool CHtiSimDirHandler::CheckImportMsg(const TDesC8& aData) - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::CheckImportMsg" ); - // Import command syntax: - // amount of fields (1 byte) __ - // type of field (1 byte) | - // length of data field (1 byte) | repeated times - // field data (variable) __| - - TInt length = aData.Length(); - if (length < 4) // min length 4 bytes - { - HTI_LOG_FORMAT( "Message too short %d", length ); - SendErrorMessageL( KErrArgument, KErrorInvalidParameters ); - return EFalse; - } - - RMobilePhoneBookStore::TMobilePhoneBookInfoV5 etelStoreInfo; - RMobilePhoneBookStore::TMobilePhoneBookInfoV5Pckg etelStoreInfoPckg(etelStoreInfo); - - TRequestStatus requestStatus; - iEtelStore.GetInfo(requestStatus, (TDes8&) etelStoreInfoPckg); - User::WaitForRequest(requestStatus); - if (requestStatus.Int() != KErrNone) - { - HTI_LOG_TEXT( "CHtiSimDirHandler: Failed to get SIM card info" ); - SendErrorMessageL(requestStatus.Int(), KErrorSimCardInfoFailed); - return EFalse; - } - TInt offset = 0; - TInt fieldCount = aData[offset]; - HTI_LOG_FORMAT( "Fields %d", fieldCount ); - if (fieldCount < 1) // must be at least one field - { - SendErrorMessageL( KErrArgument, KErrorInvalidParameters ); - return EFalse; - } - - offset++; - TInt fieldsFound = 0; - while (offset < length) - { - fieldsFound++; - TContactFieldType fieldType = (TContactFieldType) aData[offset]; - HTI_LOG_FORMAT( "Field type %d", fieldType ); - TInt maxLength = 0; - if(fieldType == ENameField) - { - maxLength = etelStoreInfo.iMaxTextLength; - } - else if(fieldType == ESecondNameField) - { - maxLength = etelStoreInfo.iMaxTextLengthSecondName; - } - else if(fieldType == EPhoneNumberField) - { - maxLength = etelStoreInfo.iMaxNumLength; - } - else if(fieldType == EEMailField) - { - maxLength = etelStoreInfo.iMaxTextLengthEmailAddr; - } - else if(fieldType == EAdditNumberField) - { - maxLength = etelStoreInfo.iMaxNumLengthAdditionalNumber; - } - else - { - HTI_LOG_TEXT("Unknown field type"); - SendErrorMessageL( KErrArgument, KErrorInvalidParameters ); - return EFalse; // invalid field type - } - - if(maxLength <= 0) - { - HTI_LOG_TEXT("Field not supported"); - SendErrorMessageL(KErrArgument, KErrorFieldNotSupported); - return EFalse; - } - - offset++; // the type of field byte - if (offset >= length) - { - SendErrorMessageL( KErrArgument, KErrorInvalidParameters ); - return EFalse; - } - TInt fieldLength = aData[offset]; - HTI_LOG_FORMAT( "Field length %d", fieldLength ); - if (fieldLength < 1) - { - SendErrorMessageL( KErrArgument, KErrorInvalidParameters ); - return EFalse; // Field data can not be empty - } - else if(fieldLength > maxLength) - { - HTI_LOG_TEXT("The length of field is too long"); - SendErrorMessageL( KErrArgument, KErrorFieldTooBig ); - return EFalse; - } - offset++; // advance over the length of data byte - offset += fieldLength; // and the field data - } - - if (offset == length && fieldsFound == fieldCount) - { - HTI_LOG_TEXT( "Message OK" ); - return ETrue; - } - - SendErrorMessageL( KErrArgument, KErrorInvalidParameters ); - return EFalse; - } - -// ---------------------------------------------------------------------------- -// CHtiSimDirHandler::SendOkMsgL -// Helper function for sending response messages. -// ---------------------------------------------------------------------------- -void CHtiSimDirHandler::SendOkMsgL(const TDesC8& aData) - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::SendOkMsgL" ); - iIsBusy = EFalse; // Done with the current request - User::LeaveIfNull(iDispatcher); - HBufC8* temp = HBufC8::NewL(aData.Length() + 1); - TPtr8 response = temp->Des(); - response.Append((TChar) CHtiPIMServicePlugin::EResultOk); - response.Append(aData); - User::LeaveIfError(iDispatcher->DispatchOutgoingMessage(temp, - KPIMServiceUid)); - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::SendOkMsgL" ); - } - -// ---------------------------------------------------------------------------- -// CHtiSimDirHandler::SendErrorMessageL -// Helper function for sending error response messages. -// ---------------------------------------------------------------------------- -void CHtiSimDirHandler::SendErrorMessageL(TInt aError, - const TDesC8& aDescription) - { - HTI_LOG_FUNC_IN( "CHtiSimDirHandler::SendErrorMessageL" ); - iIsBusy = EFalse; // Done with the current request - User::LeaveIfNull(iDispatcher); - User::LeaveIfError(iDispatcher->DispatchOutgoingErrorMessage(aError, - aDescription, KPIMServiceUid)); - HTI_LOG_FUNC_OUT( "CHtiSimDirHandler::SendErrorMessageL" ); - } - -// End of file