/*
* Copyright (c) 2002-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: Interface for sending messages.
*
*/
// INCLUDE FILES
#include "cphcltussdimp.h"
#include "cphcltussdrequesthandler.h"
#include "phcltclientserver.h"
#include <phclttypes.h>
#include <etelmm.h>
#include <f32file.h>
#include <charconv.h>
#include <gsmuelem.h>
#include <coemain.h>
//#include <phoneclient.rsg>
#include <exterror.h>
#include <gsmerror.h>
#include <etelsat.h>
#include "mphcltussdnotecontrollercallback.h"
#include "cphcltussdnotecontroller.h"
#include "cphcltussdcommonconstant.h"
#include "tflogger.h"
// CONSTANTS
const TUint8 KPhCltUssdDcsDefaultAlphabet = 0x0f; // 00001111
const TUint8 KPhCltUssdDcsAlphabetDefaultPrecededLanguage = 0x10; // 00010000
const TUint8 KPhCltUssdDcsAlphabetDefaultPrecededLanguageSkipChars3 = 3;
const TUint8 KPhCltUssdDcsAlphabetDefaultPrecededLanguageSkipChars2 = 2;
const TUint8 KPhCltUssdDcsAlphabetDefaultPrecededLanguageStartBit = 5;
const TUint8 KPhCltUssdDcsAlphabetUCS2PrecededLanguage = 0x11; // 00010001
const TUint8 KPhCltUssdDcsAlphabetUCS2PrecededLanguageSkipChars = 2;
const TUint8 KPhCltUssdDcsGeneralInformationMask = 0xc0; // 11000000
const TUint8 KPhCltUssdDcsGeneralInformation = 0x40; // 01xxxxxx
const TUint8 KPhCltUssdDcsGeneralInformationCompressed = 0x20; // xx1xxxxx
const TUint8 KPhCltUssdDcsGeneralInformationSimMask = 0x13; // 00010011
const TUint8 KPhCltUssdDcsGeneralInformationSim = 0x12; // xxx1xx10
const TUint8 KPhCltUssdDcsGeneralInformationAlphabetMask = 0x0c; // 00001100
const TUint8 KPhCltUssdDcsGeneralInformationAlphabet8Bit = 0x04; // xxxx01xx
const TUint8 KPhCltUssdDcsGeneralInformationAlphabetUCS2 = 0x08; // xxxx10xx
const TUint8 KPhCltUssdDcsMessageHandlingAlphabetMask = 0xf4; // 11110100
const TUint8 KPhCltUssdDcsMessageHandlingAlphabet8Bit = 0xf4; // 1111x1xx
const TUint8 KPhCltUssdCarriageReturn = 0x0d;
const TUint8 KPhCltUssdDcsNotSet = 0x00; // not set
// ============================= LOCAL FUNCTIONS ===============================
// CLASS DECLARATION
#ifndef TPHCLTUSSDALPHABETPACKER_H
#define TPHCLTUSSDALPHABETPACKER_H
/**
* Class for packing the Ussd string.
*/
class TPhCltUssdAlphabetPacker
{
public: // Constructors and destructor
/**
* Constructor.
*
* @param aAlphabet The used Data Coding Scheme.
* @param aIsBinary Is the data binary.
* @param aStartBit The start bit of the conversion.
*/
TPhCltUssdAlphabetPacker(
TSmsDataCodingScheme::TSmsAlphabet aAlphabet,
TBool aIsBinary,
TInt aStartBit );
public: // New functions
/**
* Pack the given string to the desired coding scheme.
*
* @param aOut The output string of packing
* @param aIn The string to be packed.
* @return The number of octets used.
*/
TInt PackL(TDes8& aOut,const TDesC8& aIn);
/**
* Convert and pack the given string to the desired coding scheme.
*
* @param aCharacterSetConverter The character converter.
* @param aFs Reference to file system.
* @param aOut The output string of packing
* @param aIn The string to be packed.
* @param aConvertedNumUDUnits The number of converted units.
* @return The number of octets used.
*/
TInt ConvertAndPackL(
CCnvCharacterSetConverter& aCharacterSetConverter,
RFs& aFs,
TDes8& aOut,
const TDesC& aIn,
TInt& aConvertedNumUDUnits );
/**
* Return information of how many octets are required when
* the aNumUDUnits number of characters is packed.
*
* @param aNumUDUnits The number of characters to be packed.
* @return The number of octets required.
*/
TInt PackedOctetsRequiredL( TInt aNumUDUnits ) const;
private:
// Private helper methods
TInt ElementSizeInBitsL() const;
private: // Data
// The Data Coding Scheme of the conversion.
TSmsDataCodingScheme::TSmsAlphabet iAlphabet;
// Information is the given descriptor binary.
TBool iIsBinary;
// The start bit of the conversion.
TInt iStartBit;
};
#endif // TPHCLTUSSDALPHABETPACKER_H
// -----------------------------------------------------------------------------
// TPhCltUssdAlphabetPacker::TPhCltUssdAlphabetPacker
//
// -----------------------------------------------------------------------------
//
TPhCltUssdAlphabetPacker::TPhCltUssdAlphabetPacker(
TSmsDataCodingScheme::TSmsAlphabet aAlphabet,
TBool aIsBinary,
TInt aStartBit)
: iAlphabet( aAlphabet ),
iIsBinary( aIsBinary ),
iStartBit( aStartBit )
{
}
// -----------------------------------------------------------------------------
// TPhCltUssdAlphabetPacker::PackL
//
// -----------------------------------------------------------------------------
//
TInt TPhCltUssdAlphabetPacker::PackL( TDes8& aOut,const TDesC8& aIn )
{
// Ensure we've got the right length
TInt packedOctetsRequired = PackedOctetsRequiredL( aIn.Length() );
if ( packedOctetsRequired > ( aOut.MaxLength() - aOut.Length() ) )
{
User::Leave( KErrOverflow );
}
// Do the conversion
TInt elementSizeInBits = ElementSizeInBitsL();
if ( elementSizeInBits == 8 ) // 8 bit data
{
// Straight copy here
aOut.Append( aIn );
}
else if ( elementSizeInBits == 7 ) // Need packing to 7-bit
{
// Get raw pointers and do packing
TUint8* outPtr = ( TUint8* )aOut.Ptr() + aOut.Length();
const TUint8* inPtr = aIn.Ptr();
outPtr[0] = 0;
for ( TInt i = 0; i < aIn.Length() ; i++ )
{
TUint8 to = inPtr[i];
*outPtr |= ( to << iStartBit );
if ( iStartBit )
{
outPtr++;
*outPtr = ( TUint8 ) ( to >> ( 8 - iStartBit ) );
}
iStartBit = ( iStartBit + 7 )%8; // roll 0,1,2,3,4,5,6,7,0,1,2,...
if ( i == aIn.Length() - 1 ) // if this is the last time
{
if ( ( to == KPhCltUssdCarriageReturn && iStartBit == 0 ) ||
iStartBit == 1 )
{
//We have to add one CR more
*outPtr |= ( KPhCltUssdCarriageReturn << iStartBit );
if ( iStartBit )
{
outPtr++;
*outPtr = ( TUint8 ) (
KPhCltUssdCarriageReturn >> ( 8 - iStartBit ) );
}
else
{
packedOctetsRequired++;
}
iStartBit = ( iStartBit + 7 )%8;
}
}
}
// Increment the length for the packed data
aOut.SetLength( aOut.Length() + packedOctetsRequired );
}
else
{
User::Invariant();
}
// Return number of bytes used
return packedOctetsRequired;
}
// -----------------------------------------------------------------------------
// TPhCltUssdAlphabetPacker::ConvertAndPackL
//
// -----------------------------------------------------------------------------
//
TInt TPhCltUssdAlphabetPacker::ConvertAndPackL(
CCnvCharacterSetConverter& aCharacterSetConverter,
RFs& aFs,
TDes8& aOut,
const TDesC& aIn,
TInt& aConvertedNumUDUnits )
{
// Do the conversion
CSmsAlphabetConverter* converter =
CSmsAlphabetConverter::NewLC(
aCharacterSetConverter, aFs, iAlphabet, iIsBinary );
TPtrC8 convertedPtr = converter->ConvertFromNativeL( aIn );
aConvertedNumUDUnits = convertedPtr.Length();
// Do the packing
TInt octetsUsed = PackL( aOut,convertedPtr );
// Cleanup and return
CleanupStack::PopAndDestroy(); // converter
return octetsUsed;
}
// -----------------------------------------------------------------------------
// TPhCltUssdAlphabetPacker::PackedOctetsRequiredL
//
// -----------------------------------------------------------------------------
//
TInt TPhCltUssdAlphabetPacker::PackedOctetsRequiredL( TInt aNumUDUnits ) const
{
TInt octetsRequired = 0;
TInt elementSizeInBits = ElementSizeInBitsL();
if ( elementSizeInBits == 8 )
{
octetsRequired=aNumUDUnits;
}
else
{
octetsRequired =
( iStartBit + aNumUDUnits*elementSizeInBits + 7 )/8; // Rounds up
}
return octetsRequired;
}
// -----------------------------------------------------------------------------
// TPhCltUssdAlphabetPacker::ElementSizeInBitsL
//
// -----------------------------------------------------------------------------
//
TInt TPhCltUssdAlphabetPacker::ElementSizeInBitsL() const
{
if ( iIsBinary )
return 8;
switch ( iAlphabet )
{
case TSmsDataCodingScheme::ESmsAlphabet7Bit:
{
return 7;
}
case TSmsDataCodingScheme::ESmsAlphabet8Bit:
case TSmsDataCodingScheme::ESmsAlphabetUCS2:
{
return 8;
}
default:
{
User::Leave( KErrGsmSMSDataCodingSchemeNotSupported );
return 8;
}
}
}
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CPhCltUssdImp::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CPhCltUssdImp* CPhCltUssdImp::NewL( TBool aShowNotes )
{
TFLOGSTRING("CPhCltUssdImp: NewL call")
CPhCltUssdImp* self = new( ELeave ) CPhCltUssdImp;
CleanupStack::PushL( self );
self->ConstructL( aShowNotes );
CleanupStack::Pop(); // self
TFLOGSTRING("CPhCltUssdImp: NewL exit")
return self;
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CPhCltUssdImp::ConstructL( TBool aShowNotes )
{
TFLOGSTRING("CPhCltUssdImp: ConstructL call")
// The note controller is needed only if the notes are shown.
iNoteController = NULL;
if ( aShowNotes )
{
iNoteController = CPhCltUssdNoteController::NewL(
*this );
}
iDCS = KPhCltUssdDcsDefaultAlphabet;
iWait = new( ELeave ) CActiveSchedulerWait;
// The one that send the request forward.
iRequestHandler = CPhCltUssdRequestHandler::NewL(
*this,
CActive::EPriorityStandard );
TFLOGSTRING("CPhCltUssdImp: ConstructL exit")
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::CPhCltUssdImp
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CPhCltUssdImp::CPhCltUssdImp()
{
TFLOGSTRING("CPhCltUssdImp: CPhCltUssdImp call_exit")
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::~CPhCltUssdImp
// Destructor.
// -----------------------------------------------------------------------------
//
CPhCltUssdImp::~CPhCltUssdImp()
{
TFLOGSTRING("CPhCltUssdImp: ~CPhCltUssdImp call")
if ( iWait )
{
if ( iWait->IsStarted() )
{
iWait->AsyncStop();
}
delete iWait;
iWait = NULL;
}
delete iRequestHandler;
iRequestHandler = NULL;
delete iNoteController;
iNoteController = NULL;
TFLOGSTRING("CPhCltUssdImp: ~CPhCltUssdImp exit")
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::HandleSendEventL
//
// Called when the Send request is completed. aError might be
// positive -> the Send is completed due received message.
// -----------------------------------------------------------------------------
//
void CPhCltUssdImp::HandleSendEventL( const TInt aError )
{
*iSendError = Min( aError , KErrNone );
TFLOGSTRING2("CPhCltUssdImp: HandleSendEventL\
aError = %d call", aError)
// iNoteController is allocated only if notes are shown.
if ( iNoteController )
{
// Send request is completed, now destroy the wait note
iNoteController->DestroyGlobalWaitNote();
// Show a different note depenging on the error code.
if ( aError <= 0 )
{
switch ( aError )
{
// All Ok.
case KErrNone:
iNoteController->ShowGlobalInformationNoteL( EPhCltUssdDone );
break;
// Operation cancelled.
case KErrCancel:
iNoteController->ShowGlobalInformationNoteL( EPhCltUssdUnconfirme );
break;
// Ongoing Ussd session or the string is barred due SS request
// or Fixed Dialling feature.
case KErrInUse:
case KErrAccessDenied:
case KErrGsmSSCallBarred:
iNoteController->ShowGlobalInformationNoteL( EPhCltUssdNotallowed );
break;
// No network coverage.
case KErrGsmSMSNoNetworkService:
iNoteController->ShowGlobalInformationNoteL(EPhCltUssdNoservice );
break;
// Offline mode.
case KErrGsmOfflineOpNotAllowed:
iNoteController->ShowGlobalInformationNoteL( EPhCltUssdOffline );
break;
case KErrSatControl:
break;
// Unknown error.
default:
iNoteController->ShowGlobalInformationNoteL( EPhCltUssdNotDone );
break;
}
}
}
// Let the original active object (one that did the send request) run again.
if ( iWait->IsStarted() )
{
iWait->AsyncStop();
}
TFLOGSTRING("CPhCltUssdImp: HandleSendEventL exit")
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::SendUssd
//
// 16-bit buffer is packed into 7-bit stream and sent.
// Default alphabet is used.
// -----------------------------------------------------------------------------
//
TInt CPhCltUssdImp::SendUssd( const TDesC& aMsgData )
{
__ASSERT_ALWAYS( aMsgData.Length() <= KPhCltUssdMax8BitCharacters,
User::Invariant() );
TRAPD( err ,
{
HBufC8* buffer8 = HBufC8::NewLC( KPhCltUssdMax7BitCharacterOctets );
TPtr8 ptr8 = buffer8->Des();
EncodeL( aMsgData , ptr8 );
User::LeaveIfError( SendUssd( ptr8 ) );
CleanupStack::PopAndDestroy(); // ptr8
});
return err;
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::SendUssd
//
// Packed buffer is send to the network with default alphabet.
// -----------------------------------------------------------------------------
//
/*****************************************************
* Series 60 Customer / ETel
* Series 60 ETel API
*****************************************************/
TInt CPhCltUssdImp::SendUssd( const TDesC8& aMsgData )
{
__ASSERT_ALWAYS( aMsgData.Length() <= KPhCltUssdMax7BitCharacterOctets,
User::Invariant() );
return SendUssd( aMsgData , iDCS );
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::SendUssd
//
// Packed buffer is sent to network with given alphabet.
// -----------------------------------------------------------------------------
//
TInt CPhCltUssdImp::SendUssd(
const TDesC8& aMsgData,
const TUint8 iSendDcs )
{
TFLOGSTRING("CPhCltUssdImp: SendUssd call")
__ASSERT_ALWAYS( aMsgData.Length() <= KPhCltUssdMax7BitCharacterOctets,
User::Invariant() );
RMobileUssdMessaging::TMobileUssdAttributesV1 attribute;
attribute.iFlags =
RMobileUssdMessaging::KUssdDataFormat +
RMobileUssdMessaging::KUssdMessageDcs;
if ( iDCS2 == KPhCltDcs7Bit )
{
attribute.iFormat = RMobileUssdMessaging::EFormatPackedString;
}
else
{
attribute.iFormat = RMobileUssdMessaging::EFormatUnspecified;
}
if ( iSendDcs == KPhCltUssdDcsNotSet ) // 0x00
{
attribute.iDcs = KPhCltUssdDcsDefaultAlphabet;
}
else
{
attribute.iDcs = iSendDcs;
}
RMobileUssdMessaging::TMobileUssdAttributesV1Pckg
attributePckg( attribute );
if ( iWait->IsStarted() )
{
return KErrInUse;
}
TInt error = KErrNone;
iSendError = &error;
TFLOGSTRING("CPhCltUssdImp: SendUssd iRequestHandler")
iRequestHandler->SendUssd( aMsgData , attributePckg );
// iNoteController is allocated only if notes are shown.
TFLOGSTRING("CPhCltUssdImp: SendUssd ShowGlobalWaitNoteL")
if ( iNoteController )
{
TRAP_IGNORE( iNoteController->ShowGlobalWaitNoteL();
);
}
TFLOGSTRING("CPhCltUssdImp: SendUssd iWait")
// Set this active object to wait the completion of the send request.
iWait->Start();
// If not deleted:
if ( iWait )
{
iSendError = NULL;
}
TFLOGSTRING("CPhCltUssdImp: SendUssd exit")
return error;
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::SendUssdCancel
//
// Cancels the out-standing request.
// -----------------------------------------------------------------------------
//
void CPhCltUssdImp::SendUssdCancel()
{
TFLOGSTRING("CPhCltUssdImp: SendUssdCancel call")
iRequestHandler->SendUssdCancel();
TFLOGSTRING("CPhCltUssdImp: SendUssdCancel exit")
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::StartUssdEditor
//
// Request Ussd App to start
// ---------------------------------------------------------------------------
//
TInt CPhCltUssdImp::StartUssdEditor() const
{
return iRequestHandler->UssdClient().StartUssdEditor();
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::AppStarting
//
// UI informs that it is been created
// -----------------------------------------------------------------------------
//
TInt CPhCltUssdImp::AppStarting()
{
TFLOGSTRING("CPhCltUssdImp: AppStarting call")
TInt res = iRequestHandler->UssdClient().AppStarting();
TFLOGSTRING2("CPhCltUssdImp: AppStarting exit res = %d",res)
return res;
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::AppTerminating
//
// UI informs that it is terminating
// -----------------------------------------------------------------------------
//
TInt CPhCltUssdImp::AppTerminating(
TPhCltUssdAppExitReason aExitReason )
{
TFLOGSTRING("CPhCltUssdImp: AppTerminating call")
TInt res = iRequestHandler->UssdClient().AppTerminating( aExitReason );
TFLOGSTRING2("CPhCltUssdImp: AppTerminating exit res = %d",res)
return res;
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::AppToForeground
//
// UI informs that it is brougth to foreground
// -----------------------------------------------------------------------------
//
TBool CPhCltUssdImp::AppToForeground()
{
TFLOGSTRING("CPhCltUssdImp: AppToForeground call")
TBool res = iRequestHandler->UssdClient().AppToForeground();
TFLOGSTRING2("CPhCltUssdImp: AppToForeground exit res = %d",res)
return res;
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::AppToBackground
//
// UI informs that it is gone background
// -----------------------------------------------------------------------------
//
TInt CPhCltUssdImp::AppToBackground()
{
TFLOGSTRING("CPhCltUssdImp: AppToBackground call")
TInt res = iRequestHandler->UssdClient().AppToBackground();
TFLOGSTRING2("CPhCltUssdImp: AppToBackground exit res = %d",res)
return res;
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::StartSAT
//
//
// -----------------------------------------------------------------------------
//
void CPhCltUssdImp::StartSAT(
TRequestStatus& aStatus,
TDes& aReceiveMessage,
TPckg< TUint >& aShowNotesAndDcs )
{
TFLOGSTRING("CPhCltUssdImp: StartSAT call")
iRequestHandler->UssdClient().StartSAT( aStatus, aReceiveMessage, aShowNotesAndDcs );
TFLOGSTRING("CPhCltUssdImp: StartSAT exit")
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::StopSAT
//
// Cancels SAT session
// -----------------------------------------------------------------------------
//
void CPhCltUssdImp::StopSAT()
{
TFLOGSTRING("CPhCltUssdImp: StopSAT call")
iRequestHandler->UssdClient().StopSAT();
TFLOGSTRING("CPhCltUssdImp: StopSAT exit")
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::GlobalWaitNoteHidden
//
// Dialog is hidden by the cancel key.
// -----------------------------------------------------------------------------
//
void CPhCltUssdImp::GlobalWaitNoteHidden()
{
TFLOGSTRING("CPhCltUssdImp: GlobalWaitNoteHidden call")
TFLOGSTRING("CPhCltUssdImp: GlobalWaitNoteHidden exit")
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::EncodeL
//
// Converts a given Uniocde string into 7-bit buffer.
// -----------------------------------------------------------------------------
//
void CPhCltUssdImp::EncodeL( const TDesC& aSrc, TDes8& aDes )
{
TFLOGSTRING("CPhCltUssdImp: EncodeL call")
aDes.Zero();
TSmsDataCodingScheme::TSmsAlphabet alphabet =
TSmsDataCodingScheme::ESmsAlphabet7Bit; // default
CCnvCharacterSetConverter* charConv = CCnvCharacterSetConverter::NewLC();
TUint cutChars = 0;
TUint startBit = 0;
if ( iDCS == KPhCltUssdDcsAlphabetDefaultPrecededLanguage )
{
alphabet = TSmsDataCodingScheme::TSmsDataCodingScheme::ESmsAlphabet7Bit;
FindFirstCarriageReturnL( aSrc , cutChars , startBit );
}
else if ( iDCS == KPhCltUssdDcsAlphabetUCS2PrecededLanguage )
{
alphabet = TSmsDataCodingScheme::ESmsAlphabetUCS2;
cutChars = KPhCltUssdDcsAlphabetUCS2PrecededLanguageSkipChars;
}
else if ( (iDCS & KPhCltUssdDcsGeneralInformationMask) ==
KPhCltUssdDcsGeneralInformation ) // General data coding information
{
//Is text compressed?
if ( iDCS & KPhCltUssdDcsGeneralInformationCompressed )
{
User::Leave( KErrNotSupported );
}
// Is SIM specific message
else if ( ( iDCS & KPhCltUssdDcsGeneralInformationSimMask )
== KPhCltUssdDcsGeneralInformationSim )
{
User::Leave( KErrAbort ); // Do not show any messages
}
// 8 bit data?
else if ( ( iDCS & KPhCltUssdDcsGeneralInformationAlphabetMask ) ==
KPhCltUssdDcsGeneralInformationAlphabet8Bit )
{
alphabet = TSmsDataCodingScheme::ESmsAlphabet8Bit;
}
// UCS2 bit data?
else if ( ( iDCS & KPhCltUssdDcsGeneralInformationAlphabetMask ) ==
KPhCltUssdDcsGeneralInformationAlphabetUCS2 )
{
alphabet = TSmsDataCodingScheme::ESmsAlphabetUCS2;
}
}
// Data coding/message handling
else if ( ( iDCS & KPhCltUssdDcsMessageHandlingAlphabetMask )
== KPhCltUssdDcsMessageHandlingAlphabet8Bit )
{
alphabet = TSmsDataCodingScheme::ESmsAlphabet8Bit;
}
TPhCltUssdAlphabetPacker* packer =
new ( ELeave ) TPhCltUssdAlphabetPacker(
alphabet, EFalse, startBit );
CleanupStack::PushL( packer );
RFs fs;
User::LeaveIfError( fs.Connect() );
CleanupClosePushL( fs );
TInt numberOfElem = 0;
// packer->ConvertAndPackL(
// *charConv , fs , aDes , aSrc , numberOfElem );
if ( alphabet == TSmsDataCodingScheme::ESmsAlphabet7Bit )
{
//TInt numberOfElem = (( aSrc.Length() - cutChars ) * 8 - startBit ) / 7;
packer->ConvertAndPackL(
*charConv , fs , aDes , aSrc.Right( aSrc.Length() - cutChars ), numberOfElem );
// DCS was 7-bit data.
iDCS2 = KPhCltDcs7Bit;
}
else // ESmsAlphabet8Bit || ESmsAlphabetUCS2
{
CSmsAlphabetConverter* converter =
CSmsAlphabetConverter::NewLC(
*charConv ,fs, alphabet, EFalse );
aDes = converter->ConvertFromNativeL(
aSrc.Right( aSrc.Length() - cutChars ) );
CleanupStack::PopAndDestroy(); //converter
if( alphabet == TSmsDataCodingScheme::ESmsAlphabet8Bit )
{
// DCS was 8-bit data.
iDCS2 = KPhCltDcs8Bit;
}
else if( alphabet == TSmsDataCodingScheme::ESmsAlphabetUCS2 )
{
//DCS was UCS2 data.
iDCS2 = KPhCltDcsUcs2;
}
// If DCS not 8-bit or UCS2, then EPhCltDcsUnknown is returned.
}
CleanupStack::PopAndDestroy(3); // fs, packer, charConv
TFLOGSTRING("CPhCltUssdImp: EncodeL exit")
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::SetDCS()
//
// Set data coding scheme
// -----------------------------------------------------------------------------
//
void CPhCltUssdImp::SetDCS( TUint8 aDCS )
{
iDCS = aDCS;
}
// -----------------------------------------------------------------------------
// CPhCltUssdImp::FindFirstCarriageReturnL
// -----------------------------------------------------------------------------
//
void CPhCltUssdImp::FindFirstCarriageReturnL(
const TDesC& aBuffer ,
TUint& aSkipChars ,
TUint& aStartBit )
{
if ( aBuffer.Length() < 3 )
{
User::Leave( KErrUnderflow );
}
aSkipChars = 0;
aStartBit = 0;
// Try out two different cases:
// 1. Find CR from thrid byte
// 2. Find CR from second byte, starting from bit 6
// 1.:
if ( aBuffer[2] == KPhCltUssdCarriageReturn )
{
aSkipChars = KPhCltUssdDcsAlphabetDefaultPrecededLanguageSkipChars3;
aStartBit = 0;
return;
}
// 2.:
// First put the pieces together and then compare
// Take last 2 bits from the second byte:
TUint result1 = aBuffer[1];
result1 = result1 >> 6;
// Take first 5 bits from the third byte:
TUint result2 = aBuffer[2];
result2 = result2 & 0x1f; // bits 0-4.
result2 = result2 << 2; // move to bits 2-6.
TUint result = result1 + result2; // 0000 00xx + 0xxx xx00
if ( result == KPhCltUssdCarriageReturn )
{
aSkipChars = KPhCltUssdDcsAlphabetDefaultPrecededLanguageSkipChars2;
aStartBit = KPhCltUssdDcsAlphabetDefaultPrecededLanguageStartBit;
return;
}
// Is was not case 1. or 2. so we are not supporting sort of string.
User::Leave( KErrNotSupported );
}
// End of File