// Copyright (c) 2006-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:
// Name : CSatNotifySetUpMenu.cpp
// Part of : Common SIM ATK TSY / commonsimatktsy
// SetUpMenu notification functionality of Sat Tsy
// Version : 1.0
//
//INCLUDES
#include <satcs.h> // Etel SAT IPC definitions
#include "CSatTsy.h" // Tsy class header
#include "CSatNotifySetUpMenu.h" // Tsy class header
#include "CSatNotificationsTsy.h" // Class header
#include "CBerTlv.h" // Ber Tlv data handling
#include "TTlv.h" // TTlv class
#include "CSatDataPackage.h" // Parameter packing
#include "TfLogger.h" // For TFLOGSTRING
#include "TSatUtility.h" // Utilities
#include "CSatTsyReqHandleStore.h" // Request handle class
#include "cmmmessagemanagerbase.h" // Message manager class for forwarding req.
// -----------------------------------------------------------------------------
// CSatNotifySetUpMenu::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CSatNotifySetUpMenu* CSatNotifySetUpMenu::NewL
(
CSatNotificationsTsy* aNotificationsTsy
)
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::NewL");
CSatNotifySetUpMenu* const satNotifySetUpMenu =
new ( ELeave ) CSatNotifySetUpMenu( aNotificationsTsy );
CleanupStack::PushL( satNotifySetUpMenu );
satNotifySetUpMenu->ConstructL();
CleanupStack::Pop( satNotifySetUpMenu );
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::NewL");
return satNotifySetUpMenu;
}
// -----------------------------------------------------------------------------
// CSatNotifySetUpMenu::~CSatNotifySetUpMenu
// Destructor
// -----------------------------------------------------------------------------
//
CSatNotifySetUpMenu::~CSatNotifySetUpMenu
(
// None
)
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::~CSatNotifySetUpMenu");
}
// -----------------------------------------------------------------------------
// CSatNotifySetUpMenu::CSatNotifySetUpMenu
// Default C++ constructor
// -----------------------------------------------------------------------------
//
CSatNotifySetUpMenu::CSatNotifySetUpMenu
(
CSatNotificationsTsy* aNotificationsTsy
) : iNotificationsTsy ( aNotificationsTsy )
{
// None
}
// -----------------------------------------------------------------------------
// CSatNotifySetUpMenu::ConstructL
// Symbian 2nd phase constructor
// -----------------------------------------------------------------------------
//
void CSatNotifySetUpMenu::ConstructL
(
// None
)
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::ConstructL");
iItemsNextIndicatorRemoved = EFalse;
}
// -----------------------------------------------------------------------------
// CSatNotifySetUpMenu::Notify
// This request allows a client to be notified of a SET UP MENU proactive
// command
// -----------------------------------------------------------------------------
//
TInt CSatNotifySetUpMenu::Notify
(
const TTsyReqHandle aTsyReqHandle,
const TDataPackage& aPackage
)
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::Notify");
// Save data pointer to client side for completion
iSetUpMenuV2Pckg = reinterpret_cast<RSat::TSetUpMenuV2Pckg*>(
aPackage.Des1n() );
// Save the request handle
iNotificationsTsy->iSatTsy->SaveReqHandle( aTsyReqHandle,
CSatTsy::ESatNotifySetUpMenuPCmdReqType );
// Check if requested notification is already pending
iNotificationsTsy->NotifySatReadyForNotification( KSetUpMenu );
return KErrNone;
}
// -----------------------------------------------------------------------------
// CSatNotifySetUpMenu::CancelNotification
// This method cancels an outstanding asynchronous
// NotifySetUpMenu request.
// -----------------------------------------------------------------------------
//
TInt CSatNotifySetUpMenu::CancelNotification
(
const TTsyReqHandle aTsyReqHandle
)
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CancelNotification");
// Reset the request handle
TTsyReqHandle reqHandle = iNotificationsTsy->iSatReqHandleStore->
ResetTsyReqHandle( CSatTsy::ESatNotifySetUpMenuPCmdReqType );
// Reset the data pointer
iSetUpMenuV2Pckg = NULL;
// Complete the request with KErrCancel
iNotificationsTsy->iSatTsy->ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// -----------------------------------------------------------------------------
// CSatNotifySetUpMenu::CompleteNotifyL
// Complete Set Up Menu notification to the client
// -----------------------------------------------------------------------------
//
TInt CSatNotifySetUpMenu::CompleteNotifyL
(
CSatDataPackage* aDataPackage,
TInt aErrorCode
)
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CompleteNotifyL");
TInt ret( KErrNone );
TInt returnValue( KErrNone );
// Unpack parameters
TPtrC8* data;
aDataPackage->UnPackData( &data );
// Reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle =
iNotificationsTsy->iSatReqHandleStore->ResetTsyReqHandle(
CSatTsy::ESatNotifySetUpMenuPCmdReqType );
TFLOGSTRING2("CSAT: CSatNotifySetUpMenu::CompleteNotifyL reqHandle is :%d",
reqHandle );
// Get ber tlv
CBerTlv berTlv;
berTlv.SetData( *data );
// Get command details tlv
CTlv commandDetails;
berTlv.TlvByTagValue( &commandDetails, KTlvCommandDetailsTag );
// Store command details tlv
iNotificationsTsy->iTerminalRespData.iCommandDetails.Copy(
commandDetails.Data() );
// Get command qualifier
TUint8 cmdQualifier( commandDetails.GetShortInfo(
ETLV_CommandQualifier ) );
TUint8 pCmdNumber( commandDetails.GetShortInfo( ETLV_CommandNumber ) );
// In case the request was ongoing, continue..
if ( CSatTsy::ESatReqHandleUnknown != reqHandle )
{
// Complete right away if error has occured, otherwise continue..
if ( KErrNone == aErrorCode )
{
RSat::TSetUpMenuV2 menu;
// Store transaction id
menu.SetPCmdNumber( pCmdNumber );
// Selection preference
menu.iPreference = RSat::ESelectionPreferenceNotSet;
if ( cmdQualifier & KSelectionUsingSoftKey )
{
menu.iPreference = RSat::ESoftKeyPreferred;
}
else
{
menu.iPreference = RSat::ENoSelectionPreference;
}
// Alpha Id string (optional)
menu.iAlphaId.iAlphaId.Zero();
// Get alpha identifier tlv
CTlv alphaIdentifier;
returnValue = berTlv.TlvByTagValue( &alphaIdentifier,
KTlvAlphaIdentifierTag );
if ( KErrNone != returnValue )
{
CreateTerminalRespL( pCmdNumber,
RSat::KErrorRequiredValuesMissing, KNullDesC16 );
ret = KErrCorrupt;
}
else
{
TUint16 alphaIdLength = alphaIdentifier.GetLength();
TFLOGSTRING2("CSAT: Alpha ID length:%d", alphaIdLength );
if ( RSat::KAlphaIdMaxSize < alphaIdLength )
{
// String too long
ret = KErrCorrupt;
}
else if ( alphaIdLength )
{
TPtrC8 temp;
// Get the alpha id
temp.Set( alphaIdentifier.GetData( ETLV_AlphaIdentifier ) );
// Convert and set the alpha id
TSatUtility::SetAlphaId( temp , menu.iAlphaId.iAlphaId );
// Set SAT toolikit name, send SAT SMS logging purpose
iToolKitName.Copy( menu.iAlphaId.iAlphaId );
TFLOGSTRING2("CSAT: CSatNotifySetUpMenu::CompleteNotifyL, \
iToolKitName:%S", &iToolKitName );
}
else
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CompleteNotifyL,\
Wrong length of alpha id.");
}
// Alpha Id status
if ( menu.iAlphaId.iAlphaId.Length() )
{
menu.iAlphaId.iStatus = RSat::EAlphaIdProvided;
}
else
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CompleteNotifyL,\
Alpha ID is NULL");
menu.iAlphaId.iStatus = RSat::EAlphaIdNull;
}
// Help information.
if ( commandDetails.GetShortInfo( ETLV_CommandQualifier )
& KHelpAvailabilityMask )
{
// Help information available
menu.iHelp = RSat::EHelpAvailable;
}
else
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CompleteNotifyL,\
No Help available");
// No help
menu.iHelp = RSat::ENoHelpAvailable;
}
// Icon identifier
TSatUtility::FillIconStructure( berTlv, menu.iIconId );
}
// Item Icon identifier list
CTlv itemsIconIdentifierList;
TInt retValue = berTlv.TlvByTagValue( &itemsIconIdentifierList,
KTlvItemIconIdentifierListTag );
TPtrC8 iconIdList;
menu.iIconListQualifier = RSat::EIconQualifierNotSet;
if ( KErrNone == retValue )
{
TUint8 iIconListQualifier( itemsIconIdentifierList.GetShortInfo(
ETLV_IconListQualifier ) );
iconIdList.Set( itemsIconIdentifierList.GetData(
ETLV_IconIdentifierList ));
if( iIconListQualifier )
{
menu.iIconListQualifier = RSat::ENotSelfExplanatory;
}
else
{
menu.iIconListQualifier = RSat::ESelfExplanatory;
}
}
else if ( KErrNotFound == retValue )
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CompleteNotifyL,\
No Icon ID");
menu.iIconListQualifier = RSat::ENoIconId;
}
else
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CompleteNotifyL, \
Wrong return value of icon identifier list.");
}
//Items Data
TInt itemNbr( 0 );
CTlv itemsData;
returnValue = berTlv.TlvByTagValue(
&itemsData, KTlvItemTag, itemNbr );
TUint8 numberOfItemData( 0 );
TUint16 stringLength( 0 );
if( !returnValue )
{
CTlv itemsDataTemp;
stringLength = ( itemsData.GetLength());
TInt ret( KErrNone );
// Set numberOfItemData
while ( KErrNone == ret )
{
numberOfItemData++;
ret = berTlv.TlvByTagValue( &itemsDataTemp, KTlvItemTag,
numberOfItemData );
}
}
// Item Next Action Indicator
CTlv itemNextActionIndicator;
retValue = berTlv.TlvByTagValue( &itemNextActionIndicator,
KTlvItemsNextActionIndicatorTag );
TPtrC8 itemNextIndicator;
if ( KErrNone == retValue )
{
TPtrC8 itemNextIndicatorTemp;
itemNextIndicatorTemp.Set( itemNextActionIndicator.GetData(
ETLV_ItemsNextActionIndicator ) );
// In case the number of items in this list does not match the
// number of items in the menu the Items Next Action Indicator
// list is ignored by ME
if( itemNextIndicatorTemp.Length() != numberOfItemData )
{
iItemsNextIndicatorRemoved = ETrue;
}
else
{
itemNextIndicator.Set( itemNextIndicatorTemp );
}
}
// If first item is NULL -> remove existing menu
if ( stringLength != 0 )
{
for ( TUint8 i = 0; ( KErrNone == ret )
&& ( KErrNone == returnValue ) ; i++ )
{
// Filling up the menu items
RSat::TItem newItem;
// Suffle through all the menu items
stringLength = 0;
TFLOGSTRING2("CSAT: CSatNotifySetUpMenu::CompleteNotifyL, \
item number:%d", i );
// Fill the new item
newItem.iItemId = itemsData.GetShortInfo(
ETLV_IdentifierOfItem );
stringLength = itemsData.GetLength();
stringLength--;
TPtrC8 itemData = itemsData.GetData(
ETLV_TextStringOfItem );
// Menu item string, coded as EFadn (3gpp 11.11)
newItem.iItemString.Zero();
if ( ( KUCS2ArabicCoding == itemData[0] )
|| ( KUCS2GreekCoding == itemData[0] )
|| ( KUCS2TurkishCoding == itemData[0] ) )
{
TSatUtility::ConvertAlphaFieldsToUnicode( itemData,
newItem.iItemString );
}
else
{
TSatUtility::Convert7BitToUnicode16( itemData,
newItem.iItemString );
}
TFLOGSTRING2("CSAT: CSatNotifySetUpMenu::CompleteNotifyL \
newItem.iItemString:%S", &newItem.iItemString );
// Adding the new menuitem
if( NULL != iconIdList.Size() && ( i < iconIdList.Length() ) )
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CompleteNotifyL \
Icons on the list" );
if( ( NULL != itemNextIndicator.Size() )
&& ( i < itemNextIndicator.Length() ) )
{
// Menu item with item next idicator and icon identifier
if ( KErrNoMemory == menu.AddItem( newItem,
itemNextIndicator[i], iconIdList[i] ) )
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::\
CompleteNotifyL, Menu item length exceeded");
// Too many or long menu items
ret = KErrCorrupt;
}
}
// Menu item with icon identifier
else if ( KErrNoMemory == menu.AddItemIcon( newItem,
iconIdList[i] ) )
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::\
CompleteNotifyL, Menu item length exceeded");
// Too many or long menu items
ret = KErrCorrupt;
}
}
// No icon on the list
else
{
if( ( NULL != itemNextIndicator.Size() )
&& ( i < itemNextIndicator.Length() ) )
{
// Menu item with item next indicator
if ( KErrNoMemory == menu.AddItem( newItem,
itemNextIndicator[i] ) )
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::\
CompleteNotifyL, Menu item length exceeded");
// Too many or long menu items
ret = KErrCorrupt;
}
}
// Menu item
else
{
TInt retAdd = menu.AddItem( newItem );
if ( KErrNoMemory == retAdd )
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::\
CompleteNotifyL, Menu item length exceeded");
// Too many or long menu items
// If there is not enough space left in the buffer used
// by the menu KErrNoMemory is returned.
ret = KErrCorrupt;
// Send terminal response
CreateTerminalRespL( pCmdNumber,
RSat::KCmdDataNotUnderstood,
KNullDesC16 );
}
}
}
itemNbr++;
returnValue = berTlv.TlvByTagValue( &itemsData,
KTlvItemTag, itemNbr );
} // End of for
}
// Set the data for the client
RSat::TSetUpMenuV2& setUpMenuV2 = ( *iSetUpMenuV2Pckg )();
setUpMenuV2 = menu;
} // End of if (KErrNone == aErrorCode)
else
{
ret = aErrorCode;
}
// Complete to the client side
TFLOGSTRING2("CSAT: Completing CSatNotifySetUpMenu: error %d",
aErrorCode );
iNotificationsTsy->iSatTsy->ReqCompleted( reqHandle, ret );
}
else
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CompleteNotifyL, \
Request not ongoing");
TBuf16<1>additionalInfo;
additionalInfo.Append ( RSat::KNoSpecificMeProblem );
CreateTerminalRespL( pCmdNumber,
RSat::KMeUnableToProcessCmd, additionalInfo );
}
return ret;
}
// -----------------------------------------------------------------------------
// CSatNotifySetUpMenu::TerminalResponseL
// Called by ETel server, passes terminal response to DOS
// -----------------------------------------------------------------------------
//
TInt CSatNotifySetUpMenu::TerminalResponseL
(
TDes8* aRsp
)
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::TerminalResponseL");
TInt ret( KErrNone );
TBuf16<1> additionalInfo;
RSat::TSetUpMenuRspV1Pckg* aRspPckg =
reinterpret_cast<RSat::TSetUpMenuRspV1Pckg*> ( aRsp );
RSat::TSetUpMenuRspV1& rspV1 = ( *aRspPckg ) ();
TUint8 pCmdNumber( rspV1.PCmdNumber() );
// Check that general result value is valid
if ( ( RSat::KSuccess != rspV1.iGeneralResult )
&& ( RSat::KMeUnableToProcessCmd != rspV1.iGeneralResult )
&& ( RSat::KCmdBeyondMeCapabilities != rspV1.iGeneralResult )
&& ( RSat::KCmdDataNotUnderstood != rspV1.iGeneralResult )
&& ( RSat::KErrorRequiredValuesMissing != rspV1.iGeneralResult)
&& ( RSat::KSuccessRequestedIconNotDisplayed !=
rspV1.iGeneralResult ) )
{
// Invalid general result
ret = KErrCorrupt;
}
// If there is Me (Mobile Entity) error, additional info is needed
if ( RSat::KMeProblem == rspV1.iInfoType )
{
// Check the length of additional info
if ( rspV1.iAdditionalInfo.Length() != 0 )
{
additionalInfo.Append( rspV1.iAdditionalInfo[0] );
}
else
{
// Invalid additional info field
ret = KErrCorrupt;
}
}
if( RSat::KSuccess == rspV1.iGeneralResult && iItemsNextIndicatorRemoved )
{
TFLOGSTRING("CSatNotifySetUpMenu::TerminalResponseL, \
iItemsNextIndicatorRemoved");
rspV1.iGeneralResult = RSat::KPartialComprehension;
}
iItemsNextIndicatorRemoved = EFalse;
CreateTerminalRespL( pCmdNumber, static_cast<TUint8>(
rspV1.iGeneralResult ), additionalInfo );
return ret;
}
// ------------------------------------------------------------------
// CSatNotifySetUpMenu::CreateTerminalRespL
// Constructs SetUpMenu specific part of terminal response and calls
// DOS to send the actual message.
// ------------------------------------------------------------------
//
TInt CSatNotifySetUpMenu::CreateTerminalRespL
(
TUint8 aPCmdNumber,
TUint8 aGeneralResult,
const TDesC16& aAdditionalInfo
)
{
TFLOGSTRING("CSAT: CSatNotifySetUpMenu::CreateTerminalRespL");
// Create and append response data
TTlv tlvSpecificData;
// Create General Result TLV here
tlvSpecificData.AddTag( KTlvResultTag );
// General result
tlvSpecificData.AddByte( aGeneralResult );
if ( RSat::KMeUnableToProcessCmd == aGeneralResult )
{
if ( aAdditionalInfo.Length() > 0 )
{
tlvSpecificData.AddByte( static_cast<TUint8>( aAdditionalInfo[0] ) );
}
}
// Prepare data
iNotificationsTsy->iTerminalRespData.iPCmdNumber = aPCmdNumber;
TPtrC8 data = tlvSpecificData.GetDataWithoutTopLevelTag();
// Pack data
CSatDataPackage dataPackage;
dataPackage.PackData( &iNotificationsTsy->iTerminalRespData, &data );
// Forward request to the DOS
return iNotificationsTsy->iSatTsy->MessageManager()->HandleRequestL(
ESatTerminalRsp, &dataPackage );
}
// End of file