cbsatplugin/atmisccmdplugin/src/scpbrcommandhandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 15 Sep 2010 12:23:51 +0300
branchRCL_3
changeset 64 1934667b0e2b
parent 54 0ba996a9b75d
permissions -rw-r--r--
Revision: 201035 Kit: 201036

/*
 * Copyright (c) 2010 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 :
 *
 */

#include "scpbrcommandhandler.h"

#include <mpbutil.h>
#include "debug.h"
#include "atmisccmdpluginconsts.h"

CSCPBRCommandHandler::CSCPBRCommandHandler( 
		MATMiscCmdPlugin* aCallback, 
		TAtCommandParser& aATCmdParser, 
		RMobilePhone& aPhone) 
		: CATCmdAsyncBase( aCallback, aATCmdParser, aPhone )
	{
    TRACE_FUNC_ENTRY
    TRACE_FUNC_EXIT
	}

CSCPBRCommandHandler::~CSCPBRCommandHandler()
	{
    TRACE_FUNC_ENTRY
    Cancel();
    iPhoneBookStore.Close();
    iCustomApi.Close();
    iReply.Close();
    delete iPhoneBookBuffer;
    iEntries.Close();
    iContactsBuf.Close();
    TRACE_FUNC_EXIT
	}

void CSCPBRCommandHandler::ConstructL()
	{
    TRACE_FUNC_ENTRY
    TInt err = iPhoneBookStore.Open( iPhone, KETelIccAdnPhoneBook);
    if( err != KErrNone )  // if the phonebookstore can't be opened or error occurs when try to open it.
        {
        iState = ESCPBRStateNotSupported;
        TRACE_FUNC_EXIT
        return;
        }
    err = iCustomApi.Open( iPhone );
    if( err != KErrNone )  // If the custom api can't be opened.
        {
        iPhoneBookStore.Close();
        iState = ESCPBRStateNotSupported;
        TRACE_FUNC_EXIT
        return;
        }
    iReply.CreateL( KBufBlockSize );
	iPhoneBookBuffer = new ( ELeave ) CPhoneBookBuffer();	
    TRACE_FUNC_EXIT
	}

CSCPBRCommandHandler* CSCPBRCommandHandler::NewL( 
		MATMiscCmdPlugin* aCallback, 
		TAtCommandParser& aATCmdParser, 
		RMobilePhone& aPhone )
	{
    TRACE_FUNC_ENTRY
	CSCPBRCommandHandler * self = new ( ELeave ) CSCPBRCommandHandler( aCallback, aATCmdParser, aPhone );
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
    TRACE_FUNC_EXIT
	return self;
	}

void CSCPBRCommandHandler::HandleCommand(const TDesC8& /*aCmd*/, RBuf8& /*aReply*/, TBool /*aReplyNeeded*/ )
	{
    TRACE_FUNC_ENTRY
    if( iState == ESCPBRStateIdle )  // Not supported or have unfinished task.
        {
        iReply.Zero();  
        TAtCommandParser::TCommandHandlerType cmdHandlerType = iATCmdParser.CommandHandlerType();
        switch( cmdHandlerType )
            {
            case TAtCommandParser::ECmdHandlerTypeTest: // command: AT^SCPBR=?
                {
                if( iTotalEntries == 0 )
                    {
                    iState = ESCPBRStateGetPhoneBookInfo;
                    RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg pkg( iPhoneBookInfo );
                    iPhoneBookStore.GetInfo( iStatus, pkg );
                    SetActive();
                    }
                else if ( iMLength ==0 )
                    {
                    iState = ESCPBRStateGet3GPBInfo;
                    iCustomApi.Get3GPBInfo( iStatus, i3GPBInfo );
                    SetActive();
                    }
                else
                    {
                    iReply.Format( KSCPBRSupportedEntriesIndexList, 
                            iTotalEntries, iNLength, iTLength, iMLength );
                    iCallback->CreateReplyAndComplete( EReplyTypeOk, iReply );
                    }
                break;
                }
            case TAtCommandParser::ECmdHandlerTypeSet:  // command: AT^SCPBR=<index1>[,<index2>]
                {
                if( ParseParameters() == KErrNone )
                    {
                    iEntries.Reset();
                    TInt amountOfEntries = iIndex2 - iIndex1 + 1;  // the amount of entries.
                    Trace( _L8("The amount of entries: %d "), amountOfEntries );
                    iContactsBuf.Zero();
                    TInt bufSize;
                    if( amountOfEntries >= KSCPBRMaxEntryCount )
                        {
                        bufSize= KSCPBRMaxEntryCount * KSCPBRDefaultSizeOfOneEntry;
                        amountOfEntries = KSCPBRMaxEntryCount;
                        }
                    else
                        {
                        bufSize = amountOfEntries * KSCPBRDefaultSizeOfOneEntry;
                        }
                    
                    if( bufSize >= iContactsBuf.MaxLength() )
                        {
                        TInt err = iContactsBuf.ReAlloc( bufSize );
                        Trace( _L8("The error code of the realloc: %d "), err );
                        if( err != KErrNone )
                            {
                            iState = ESCPBRStateIdle;
                            iCallback->CreateReplyAndComplete( EReplyTypeError );
                            break;
                            }
                        }
                    iState = ESCPBRStateRead;
                    iPhoneBookStore.Read( iStatus,  iIndex1, amountOfEntries, iContactsBuf );
                    SetActive();
                    }
                else
                    {
                    iCallback->CreateReplyAndComplete( EReplyTypeError );
                    }
                break;
                }
            default:
                {
                iCallback->CreateReplyAndComplete( EReplyTypeError );
                break;
                }
            }
        }
    else
        {
        iCallback->CreateReplyAndComplete( EReplyTypeError );
        } 
       TRACE_FUNC_EXIT
	}

TInt CSCPBRCommandHandler::ParseParameters()
    {
    TRACE_FUNC_ENTRY
    iIndex1 = 0; 
    iIndex2 = 0;
    TInt index3;
    TInt ret1 = iATCmdParser.NextIntParam( iIndex1 );
    TInt ret2 = iATCmdParser.NextIntParam( iIndex2 );
    TInt ret3 = iATCmdParser.NextIntParam( index3 );
    
    if( ret1 != KErrNone 
            || ( ret2 != KErrNone && ret2 != KErrNotFound )
            || ret3 != KErrNotFound )
        {
        TRACE_FUNC_EXIT
        return KErrArgument;
        }
    if( ret2 == KErrNotFound )
        {
        iIndex2 = iIndex1;
        }
    if (iIndex2 < iIndex1)
        {
        TRACE_FUNC_EXIT
        return KErrArgument;
        }
    TRACE_FUNC_EXIT
    return KErrNone;
    }

void CSCPBRCommandHandler::RunL()
	{
    TRACE_FUNC_ENTRY
    iReply.Zero();
    TInt result = iStatus.Int();
    if( result == KErrNone )
        {
        switch( iState )
            {
            case ESCPBRStateRead:
                {
                ExtractEntriesL();
                FormatReplyL();
                iState = ESCPBRStateIdle;
                iCallback->CreateReplyAndComplete(EReplyTypeOk, iReply);
                break;
                }
            case ESCPBRStateGetPhoneBookInfo:
                {
                iTotalEntries = iPhoneBookInfo.iTotalEntries;
                iNLength = iPhoneBookInfo.iMaxNumLength;
                iTLength = iPhoneBookInfo.iMaxTextLength;
                if (iMLength == 0)
                    {
                    iState = ESCPBRStateGet3GPBInfo;
                    iCustomApi.Get3GPBInfo( iStatus, i3GPBInfo );
                    SetActive();
                    }
                else 
                    {
                    iReply.Format( KSCPBRSupportedEntriesIndexList, 
                            iTotalEntries, iNLength, iTLength, iMLength );
                    iState = ESCPBRStateIdle;
                    iCallback->CreateReplyAndComplete( EReplyTypeOk, iReply );
                    }
                break;
                }
            case ESCPBRStateGet3GPBInfo:
                {
                iMLength = i3GPBInfo.iMaxLenEmail;
                iReply.Format( KSCPBRSupportedEntriesIndexList, 
                        iTotalEntries, iNLength, iTLength, iMLength );
                iState = ESCPBRStateIdle;
                iCallback->CreateReplyAndComplete( EReplyTypeOk, iReply );
                break;
                }
            default: 
                {
                iState = ESCPBRStateIdle;
                iCallback->CreateReplyAndComplete( EReplyTypeError );
                break;
                }
            }
        }
    else
        {
        iState = ESCPBRStateIdle;
        iCallback->CreateCMEReplyAndComplete( result );
        }
    TRACE_FUNC_EXIT
	}

TInt CSCPBRCommandHandler::RunError(TInt aError)
    {
    TRACE_FUNC_ENTRY
    iState = ESCPBRStateIdle;
    iCallback->CreateReplyAndComplete( EReplyTypeError );
    TRACE_FUNC_EXIT
    return KErrNone;
    }

void CSCPBRCommandHandler::ExtractEntriesL()
    {
    TRACE_FUNC_ENTRY
    iPhoneBookBuffer->Set( &iContactsBuf );
    iPhoneBookBuffer->StartRead();
    TUint8 fieldTag;
    CPhoneBookBuffer::TPhBkTagType dataType;
    TInt numCount = 0;
	// clear entry arry for use.
    iEntries.Reset();
    User::LeaveIfError(iPhoneBookBuffer->GetTagAndType( fieldTag, dataType ));
    if( fieldTag != RMobilePhoneBookStore::ETagPBNewEntry )
        {
        // Buffer corrupt
        User::Leave(KErrCorrupt);
        }
    TInt ret = KErrNone;
    TInt index = -1; // at least one entry
    while (ret != KErrNotFound) // if reach the buffer end.
        {
        switch (fieldTag)
            {
            case RMobilePhoneBookStore::ETagPBNewEntry:
                {
                TPhoneBookEntry entry;
                iEntries.AppendL(entry);
                ++index;
                numCount = 0; // set the number count of new entry to 0. 
                break;
                }
            case RMobilePhoneBookStore::ETagPBAdnIndex:
                {
                TUint16 simIndex = 0;
                if (dataType != CPhoneBookBuffer::EPhBkTypeInt16)
                    {
                    User::Leave(KErrCorrupt);
                    }
                User::LeaveIfError( iPhoneBookBuffer->GetValue(simIndex) );

                iEntries[index].iIndex = simIndex;
                break;
                }
            case RMobilePhoneBookStore::ETagPBText:
                {
                TPtrC16 text;
                if (dataType != CPhoneBookBuffer::EPhBkTypeDes16)
                    {
                    User::Leave(KErrCorrupt);
                    }
                User::LeaveIfError( iPhoneBookBuffer->GetValue(text) );
                CopyToPhonebookEntryField(iEntries[index].iName, text);
                break;
                }
            case RMobilePhoneBookStore::ETagPBNumber:
                {
                TPtrC16 number;
                if (dataType != CPhoneBookBuffer::EPhBkTypeDes16)
                    {
                    User::Leave(KErrCorrupt);
                    }
                User::LeaveIfError( iPhoneBookBuffer->GetValue(number) );
                ++numCount;
                switch (numCount)
                    {
                    case 1: // The first number
                        CopyToPhonebookEntryField(iEntries[index].iNumber1, number);
                        break;
                    case 2: // The Second number
                        CopyToPhonebookEntryField(iEntries[index].iNumber2, number);
                        break;
                    case 3: // the Third number
                        CopyToPhonebookEntryField(iEntries[index].iNumber3, number);
                        break;
                    case 4: // the fourth number.
                        CopyToPhonebookEntryField(iEntries[index].iNumber4, number);
                        break;
                    }
                break;
                }
            case RMobilePhoneBookStore::ETagPBEmailAddress:
                {
                TPtrC16 email;
                if (dataType != CPhoneBookBuffer::EPhBkTypeDes16)
                    {
                    User::Leave(KErrCorrupt);
                    }
                User::LeaveIfError( iPhoneBookBuffer->GetValue(email) );
                CopyToPhonebookEntryField(iEntries[index].iEmail, email);
                break;
                }
            default:
                {
                iPhoneBookBuffer->SkipValue(dataType);
                break;
                }
            }
        ret = iPhoneBookBuffer->GetTagAndType(fieldTag, dataType);
        }
 
    TRACE_FUNC_EXIT
    }

void CSCPBRCommandHandler::CopyToPhonebookEntryField(TDes8& aDest, const TDesC16& aSrc)
    {
    TRACE_FUNC_ENTRY
    TInt maxLength = aDest.MaxLength();
    if ( aSrc.Length() <= maxLength )
        {
        aDest.Copy(aSrc);
        }
    else
        {
        aDest.Copy( aSrc.Left(maxLength) );
        }
    TRACE_FUNC_EXIT    
    }

void CSCPBRCommandHandler::FormatReplyL()
    {
    TRACE_FUNC_ENTRY

    TInt count = iEntries.Count();
    for (TInt i = 0; i < count; ++i)
        {
        AppendEntryL(iEntries[i]);
        }
    iReply.Append(KCRLF);
    
    TRACE_FUNC_EXIT
    }

void CSCPBRCommandHandler::AppendEntryL(const TPhoneBookEntry& aEntry)
    {
    TRACE_FUNC_ENTRY
    TBuf8<KSCPBRDefaultSizeOfOneEntry> entryBuffer;
    aEntry.Externalize(entryBuffer);
    
    TInt length = entryBuffer.Length() + KSCPBR().Length(); 
    if (length + iReply.Length() > iReply.MaxLength())
        {
        iReply.ReAllocL(iReply.MaxLength()+KBufBlockSize);
        }
    
    iReply.Append(KSCPBR);
    iReply.Append(entryBuffer);
    TRACE_FUNC_EXIT
    }

void CSCPBRCommandHandler::DoCancel()
	{
    TRACE_FUNC_ENTRY
    switch( iState )
        {
        case ESCPBRStateRead:
            {
            iPhoneBookStore.CancelAsyncRequest( EMobilePhoneStoreRead );
            break;
            }
        case ESCPBRStateGetPhoneBookInfo:
            {
            iPhoneBookStore.CancelAsyncRequest( EMobilePhoneStoreGetInfo );
            break;
            }
        case ESCPBRStateGet3GPBInfo:
            {
            iPhoneBookStore.CancelAsyncRequest( EGet3GPBInfoIPC );
            break;
            }
        default:
            break;
        }
    iState = ESCPBRStateIdle;
    TRACE_FUNC_EXIT
	}


void CSCPBRCommandHandler::TPhoneBookEntry::Externalize(TDes8& aDes) const
    {
    TRACE_FUNC_ENTRY
    
    aDes.Format(KSCPBRReplyOneEntry, iIndex, &iNumber1, &iNumber2, &iNumber3, &iNumber4, &iName, &iEmail);
    
    TRACE_FUNC_EXIT
    }