--- a/adaptationlayer/tsy/nokiatsy_dll/src/cmmsmsmesshandler.cpp Mon Nov 09 10:36:19 2009 +0000
+++ b/adaptationlayer/tsy/nokiatsy_dll/src/cmmsmsmesshandler.cpp Thu Jan 14 10:44:58 2010 +0200
@@ -39,9 +39,9 @@
#include "cmmphonemesshandler.h"
#include "tsylogger.h"
#include "cmmphonetsender.h"
-#include "osttracedefinitions.h"
+#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
-#include "cmmsmsmesshandlertraces.h"
+#include "cmmsmsmesshandlerTraces.h"
#endif
// External Data Structures
@@ -83,6 +83,17 @@
// const TUint8 KSizeOfAlphaTag( 34 ); Compiler warning removal
const TUint8 KSmsScTimeStampMaxLength( 7 );
+// Constanst for SMS parameters
+const TUint8 KSmsMandatoryParamsLength( 28 );
+const TUint8 KSmsMaxAddressLength( 12 );
+const TUint8 KSmsParamsParamIndicatorOffset( 0 );
+const TUint8 KSmsParamsDestAddressOffset( 1 );
+const TUint8 KSmsParamsScAddressOffset( 13 );
+const TUint8 KSmsParamsProtocolIdOffset( 25 );
+const TUint8 KSmsParamsDcsOffset( 26 );
+const TUint8 KSmsParamsValidityPeriodOffset( 27 );
+const TUint8 KSizeOfAlphaTag( 62 );
+
// MODULE DATA STRUCTURES
// Local Data Structures
@@ -175,6 +186,11 @@
iReceivedClass2ToBeReSent = EFalse;
// default bearer setting is "CS preferred"
iMobileSmsBearer = RMobileSmsMessaging::ESmsBearerCircuitPreferred;
+
+ iMemoryCapacityExceeded = EFalse;
+
+ // Reading of SMSP entries starts from record 1
+ iSmspRecordNumber = 1;
}
// -----------------------------------------------------------------------------
@@ -297,6 +313,26 @@
if ( RMobileSmsMessaging::KGsmTpduSize >= sendData.iMsgData->Length() )
{
msgData.Append( *sendData.iMsgData );
+
+ // Get TP-MTI (TP-Message-Type-Indicator) from first octet of TPDU
+ TUint8 tpMti( msgData[KTpduIndexMessageParameters] &
+ TSmsFirstOctet::ESmsMTIMask );
+ if ( TSmsFirstOctet::ESmsMTISubmitOrSubmitReport == tpMti )
+ {
+ subBlockId = SMS_SB_SUBMIT;
+ }
+ else if ( TSmsFirstOctet::ESmsMTIStatusReportOrCommand == tpMti )
+ {
+ subBlockId = SMS_SB_COMMAND;
+ }
+ else // Message type not supported
+ {
+ ret = CMmStaticUtility::EpocErrorCode(
+ KErrArgument,
+ KErrGsmSMSTpduNotSupported );
+TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsMessageSendReq. Error! SMS type not supported: %d", tpMti);
+OstTraceExt1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_SMSMESSAGESENDREQ, "CMmSmsMessHandler::SmsMessageSendReq.Error! SMS type not supported;tpMti=%hhu", tpMti );
+ }
}
else
{
@@ -319,26 +355,6 @@
OstTraceExt2( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_SMSMESSAGESENDREQ, "CMmSmsMessHandler::SmsMessageSendReq.Error!;msgAttr->iFlags=%d;msgAttr->iDataFormat=%hhu", msgAttr->iFlags, msgAttr->iDataFormat );
}
- // Get TP-MTI (TP-Message-Type-Indicator) from first octet of TPDU
- TUint8 tpMti( msgData[KTpduIndexMessageParameters] &
- TSmsFirstOctet::ESmsMTIMask );
- if ( TSmsFirstOctet::ESmsMTISubmitOrSubmitReport == tpMti )
- {
- subBlockId = SMS_SB_SUBMIT;
- }
- else if ( TSmsFirstOctet::ESmsMTIStatusReportOrCommand == tpMti )
- {
- subBlockId = SMS_SB_COMMAND;
- }
- else // Message type not supported
- {
- ret = CMmStaticUtility::EpocErrorCode(
- KErrArgument,
- KErrGsmSMSTpduNotSupported );
-TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsMessageSendReq. Error! SMS type not supported: %d", tpMti);
-OstTraceExt1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_SMSMESSAGESENDREQ, "CMmSmsMessHandler::SmsMessageSendReq.Error! SMS type not supported;tpMti=%hhu", tpMti );
- }
-
#if (NCP_COMMON_S60_VERSION_SUPPORT>S60_VERSION_32)
// Check whether there is SMS sending ongoing.
if ( iSMSSendingOngoing )
@@ -592,13 +608,11 @@
tpUdl,
tpUserDataIndex,
defaultAlphabet,
- msgOffset
- );
+ msgOffset );
numOfSubblocks++;
- msgOffset += lengthOfSMSUserDataSb + 1; // Add one byte to put offset into
- // next free position.
-TFLOGSTRING("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_USER_DATA created." );
-OstTrace0( TRACE_NORMAL, DUP7_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_USER_DATA created." );
+ msgOffset += lengthOfSMSUserDataSb;
+TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_USER_DATA created. Message offset: %d", msgOffset );
+OstTraceExt1( TRACE_NORMAL, DUP7_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_USER_DATA created.;msgOffset=%hhu", msgOffset );
}
// Create SMS_SB_CHECK_INFO subblock if user data exists
@@ -649,6 +663,7 @@
{
trId = ESmsMessagingResumeSmsReception;
}
+
TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_SMS );
isiMsg.Set8bit(
@@ -1215,6 +1230,15 @@
smsServerCauseType,
smsServerCauseValue ) );
+ if ( KErrNone == epocError )
+ {
+ // even if client deactivates reception, next time it is activated
+ // SMS server will ask network to resend all NACKed MT SMs
+ // only query status does not affect this flag, but this action
+ // is not used
+ iMemoryCapacityExceeded = EFalse;
+ }
+
// Compete active reception status
if ( SMS_RECEPTION_ACTIVE == receptionStatus )
{
@@ -1412,38 +1436,52 @@
{
TFLOGSTRING("TSY: CMmSmsMessHandler::SmsReceivedMsgInd");
OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSPPROUTINGNTF, "CMmSmsMessHandler::SmsReceivedMsgInd" );
- TInt ret( KErrNone );
- // Create a package
- CMmDataPackage package;
-
- TUint8 replaceTpPid( 0 ); // IsSmsClass2 also fills this
- TBool receivedSmsClass2( IsSmsClass2( aIsiMsg, replaceTpPid ) );
-
- // SIM SMS cache: incoming class 2 SMS
- if ( receivedSmsClass2 )
+
+ if ( iMemoryCapacityExceeded )
{
- ret = SmsClass2ReceivedMsgInd( aIsiMsg, replaceTpPid );
+TFLOGSTRING("TSY: CMmSmsMessHandler::SmsReceivedMsgInd no storage - internal NACK");
+OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSRECEIVEDMSGIND, "CMmSmsMessHandler::SmsReceivedMsgInd no storage - internal NACK" );
+ // error is ignored
+ SmsReceivedMsgReportReq(
+ EInternalNack,
+ NULL,
+ KErrGsmSMSMemoryCapacityExceeded );
}
- // Received SMS is not a class 2 SMS (it is a normal SMS)
else
{
- ret = SmsClass1ReceivedMsgInd( aIsiMsg );
- }
- // There was an error, complete to upper level
- if ( KErrNone != ret )
- {
+ TInt ret( KErrNone );
+ // Create a package
+ CMmDataPackage package;
+
+ TUint8 replaceTpPid( 0 ); // IsSmsClass2 also fills this
+ TBool receivedSmsClass2( IsSmsClass2( aIsiMsg, replaceTpPid ) );
+
+ // SIM SMS cache: incoming class 2 SMS
+ if ( receivedSmsClass2 )
+ {
+ ret = SmsClass2ReceivedMsgInd( aIsiMsg, replaceTpPid );
+ }
+ // Received SMS is not a class 2 SMS (it is a normal SMS)
+ else
+ {
+ ret = SmsClass1ReceivedMsgInd( aIsiMsg );
+ }
+ // There was an error, complete to upper level
+ if ( KErrNone != ret )
+ {
TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsReceivedMsgInd;ret=%d", ret);
OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSPPROUTINGNTF, "CMmSmsMessHandler::SmsReceivedMsgInd;ret=%d", ret );
- TBool smsInd( ETrue );
- TSmsMsg* nullSms = NULL;
-
- package.PackData( &smsInd, &nullSms );
-
- // Complete request to client
- iMessageRouter->Complete(
- EMobileSmsMessagingReceiveMessage,
- &package,
- ret );
+ TBool smsInd( ETrue );
+ TSmsMsg* nullSms = NULL;
+
+ package.PackData( &smsInd, &nullSms );
+
+ // Complete request to client
+ iMessageRouter->Complete(
+ EMobileSmsMessagingReceiveMessage,
+ &package,
+ ret );
+ }
}
}
@@ -1463,52 +1501,72 @@
TFLOGSTRING3("TSY: CMmSmsMessHandler::SmsReceivedPpReportResp - traId: %d, cause: %d", traId, cause);
OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSRECEIVEDPPREPORTRESP, "CMmSmsMessHandler::SmsReceivedPpReportResp;traId=%hhu;cause=%hhu", traId, cause );
- // Response for SmsReceivedPpReportReq (Ack)
- if ( ESmsMessagingAckSmsStored == traId )
+ if ( iMemoryCapacityExceeded )
{
- iMessageRouter->Complete(
- EMobileSmsMessagingAckSmsStored,
- CMmStaticUtility::CSCauseToEpocError(
- PN_SMS,
- SMS_CAUSE_TYPE_COMMON,
- cause ) );
- }
- // Response for SmsReceivedPpReportReq (Nack)
- else if ( ESmsMessagingNackSmsStored == traId )
- {
- iMessageRouter->Complete(
- EMobileSmsMessagingNackSmsStored,
- CMmStaticUtility::CSCauseToEpocError(
- PN_SMS,
- SMS_CAUSE_TYPE_COMMON,
- cause ) );
+ // ignore the response, this is response to self-NACK
+ // caused by client not having anymore storage space
+TFLOGSTRING("TSY: CMmSmsMessHandler::SmsReceivedPpReportResp - self-NACK");
+OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSRECEIVEDMSGREPORTRESP, "CMmSmsMessHandler::SmsReceivedPpReportResp - self-NACK" );
}
else
{
+ // Response for SmsReceivedPpReportReq (Ack)
+ if ( ESmsMessagingAckSmsStored == traId )
+ {
+ iMessageRouter->Complete(
+ EMobileSmsMessagingAckSmsStored,
+ CMmStaticUtility::CSCauseToEpocError(
+ PN_SMS,
+ SMS_CAUSE_TYPE_COMMON,
+ cause ) );
+ }
+ // Response for SmsReceivedPpReportReq (Nack)
+ else if ( ESmsMessagingNackSmsStored == traId ||
+ ESmsMessagingNackSmsStoredCapacityExceeded == traId )
+ {
+ iMessageRouter->Complete(
+ EMobileSmsMessagingNackSmsStored,
+ CMmStaticUtility::CSCauseToEpocError(
+ PN_SMS,
+ SMS_CAUSE_TYPE_COMMON,
+ cause ) );
+ }
+ else
+ {
TFLOGSTRING2("TSY:CMmSmsMessHandler::SmsReceivedPpReportResp:Unexpected transaction ID %d.",traId);
OstTraceExt1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSRECEIVEDPPREPORTRESP, "CMmSmsMessHandler::SmsReceivedPpReportResp;Unexpected transaction ID=%hhu", traId );
- }
-
- if ( KErrNone != cause )
- {
- //Acknowledging failed.
- //Complete possible receive message request with KErrGeneral and
- //set routing activity to false. SMS Stack makes new ReceiveMessage
- //request.
- TBool smsInd( EFalse );
- TSmsMsg* nullSms = NULL;
-
- //Complete request to client
- CMmDataPackage package;
- package.PackData( &smsInd, &nullSms );
- iSmsSlotLocation = 0;
-
- // ISI message construction failed or phonet sender
- // returned error
- iMessageRouter->Complete(
- EMobileSmsMessagingReceiveMessage,
- &package,
- KErrGeneral );
+ }
+
+ if ( SMS_OK != cause )
+ {
+ //Acknowledging failed.
+ //Complete possible receive message request with KErrGeneral and
+ //set routing activity to false. SMS Stack makes new ReceiveMessage
+ //request.
+ //Client continues receiving MT SM indications if NACKing failed
+ iMemoryCapacityExceeded = EFalse;
+
+ TBool smsInd( EFalse );
+ TSmsMsg* nullSms = NULL;
+
+ //Complete request to client
+ CMmDataPackage package;
+ package.PackData( &smsInd, &nullSms );
+ iSmsSlotLocation = 0;
+
+ // ISI message construction failed or phonet sender
+ // returned error
+ iMessageRouter->Complete(
+ EMobileSmsMessagingReceiveMessage,
+ &package,
+ KErrGeneral );
+ }
+ else if ( ESmsMessagingNackSmsStoredCapacityExceeded == traId )
+ {
+ // client succeeded NACKing MT SM
+ // it wont receive any further MT SM indications
+ iMemoryCapacityExceeded = ETrue;
+ }
}
}
@@ -1748,12 +1806,15 @@
}
case EMobileSmsMessagingGetSmspListPhase1:
{
- // Lets delete TSY's internal temporary SMSP storage
+ // Reset internal temporary SMSP storage
iSmspListArray->ResetAndDestroy();
+ // Start reading SMSP entries
+ ret = UiccGetSmspEntryReq();
break;
}
case EMobileSmsMessagingStoreSmspList:
{
+ ret = UiccSmsUpdateParameterReq( aDataPackage );
break;
}
case EMobileSmsMessagingAckSmsStored:
@@ -1790,8 +1851,12 @@
OstTrace0( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_EXTFUNCL, "CMmSmsMessHandler::ExtFuncL, Internal Nack handling started" );
}
+ // NACK due to lack of storage space causes NTSY to reject further
+ // MT SMs until client resumes SMS reception
+ TUint8 traId = KErrGsmSMSMemoryCapacityExceeded == rpCause ?
+ ESmsMessagingNackSmsStoredCapacityExceeded : ESmsMessagingNackSmsStored;
ret = SmsReceivedMsgReportReq(
- ESmsMessagingNackSmsStored,
+ traId,
msgData,
rpCause );
break;
@@ -1803,6 +1868,7 @@
}
case EMobilePhoneStoreDeleteAll:
{
+ iRecordId = 1; // Start fron 1st location
ret = DeleteAllSms();
break;
}
@@ -1853,7 +1919,13 @@
if ( smsFromCache )
{
- delete smsFromCache;
+ if ( CheckSCTimestamp( *smsFromCache, scTime ) )
+ {
+ // Message with the same timestamp found,
+ // update SIM flag.
+ UiccUpdateSMSStatus( currentSlot );
+ currentSlot = totalSlots; // we're done, exit loop
+ }
}
currentSlot++;
}
@@ -1880,41 +1952,6 @@
return ret;
}
-// -----------------------------------------------------------------------------
-// CMmSmsMessHandler::InternalRetrieveSmspListL
-// Complete SmsParametersReadREQuest and call GetSmspList
-// or CompleteReadSmsp method
-// (other items were commented in header)
-// -----------------------------------------------------------------------------
-//
-void CMmSmsMessHandler::InternalRetrieveSmspListL( TSmsParameters* aParameters )
- {
-TFLOGSTRING("TSY: CMmSmsMessHandler::InternalRetrieveSmspListL");
-OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_INTERNALRETRIEVESMSPLISTL, "CMmSmsMessHandler::InternalRetrieveSmspListL" );
- // Add parameter sets information to the TSY's internal storage
- iSmspListArray->AppendL( aParameters );
-
- // Lets read next SMSP set
- if ( iLocationOfSmspSet <= iAmountOfSmspSets )
- {
- iLocationOfSmspSet++;
- }
- else // All SMSP sets read
- {
- //Pack data
- CMmDataPackage package;
- package.PackData( iSmspListArray );
-
- //complete the request,
- iMessageRouter->Complete(
- EMobileSmsMessagingGetSmspListPhase1,
- &package,
- KErrNone );
-
- //Delete array
- iSmspListArray->ResetAndDestroy();
- }
- }
// -----------------------------------------------------------------------------
// CMmSmsMessHandler::CheckTpPidAndSenderAndServiceCenter
@@ -1939,9 +1976,11 @@
// Destination address length is integer representation
// of the number of useful semi-octets of address field
- messageReference = ( messageReference + 1 ) / 2;
+ // Add two mandatory bytes of TP-OA, too.
+
+ messageReference = ( ( messageReference + 1 ) / 2) + 2;
offset += messageReference;
- offset += 2; // Set offset to Protocol Id
+
TUint8 protocolId( aSMSOnSIM->iMsgData[offset] );
if ( protocolId == aReceivedTpPid )
{
@@ -2127,7 +2166,43 @@
TInt index( 0 );
//unpack data
aDataPackage->UnPackData( index );
- iSmsCache.SetDeleteLocation( index );
+ RMobileSmsStore::TMobileGsmSmsEntryV1* smsData(
+ iSmsCache.GetEntry( index ) );
+
+ if ( smsData )
+ {
+ iSmsCache.SetDeleteLocation( index );
+
+ // Set parameters for UICC_APPL_CMD_REQ message
+ TUiccWriteLinearFixed params;
+ params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+ params.trId = ETrIdDeleteSMS;
+ params.dataOffset = 0;
+ params.dataAmount = 0;
+ params.record = index;
+
+ params.fileId = KElemFileShortMessages;
+ params.fileIdSfi = UICC_SFI_NOT_PRESENT;
+ params.serviceType = UICC_APPL_UPDATE_LINEAR_FIXED;
+
+ // File id path
+ params.filePath.Append( KMasterFileId >> 8 );
+ params.filePath.Append( KMasterFileId );
+ params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+ // Update file data with 0xFF
+ TBuf8<KSmsElemetaryFileRecordLength> fileDataBuf;
+ fileDataBuf.AppendFill( 0xFF, KSmsElemetaryFileRecordLength );
+
+ params.fileData.Append( fileDataBuf );
+
+ return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+ }
+ else
+ {
+ // Location empty or not in use.
+ iMessageRouter->Complete( EMobilePhoneStoreDelete, KErrNone );
+ }
}
else
{
@@ -2151,6 +2226,50 @@
// SIM SMS cache: -- EMobilePhoneStoreDeleteAll
if ( KErrNone == iSmsCache.Status() )
{
+ if ( 0 < iSmsCache.TotalEntries() )
+ {
+ RMobileSmsStore::TMobileGsmSmsEntryV1* smsData(
+ iSmsCache.GetEntry( iRecordId ) );
+
+ if ( smsData )
+ {
+ iSmsCache.SetDeleteLocation( iRecordId );
+
+ // Set parameters for UICC_APPL_CMD_REQ message
+ TUiccWriteLinearFixed params;
+ params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+ params.trId = ETrIdDeleteAllSMSs;
+ params.dataOffset = 0;
+ params.dataAmount = 0;
+ params.record = iRecordId;
+
+ params.fileId = KElemFileShortMessages;
+ params.fileIdSfi = UICC_SFI_NOT_PRESENT;
+ params.serviceType = UICC_APPL_UPDATE_LINEAR_FIXED;
+
+ // File id path
+ params.filePath.Append( KMasterFileId >> 8 );
+ params.filePath.Append( KMasterFileId );
+ params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+ // Update file data with 0xFF
+ TBuf8<KSmsElemetaryFileRecordLength> fileDataBuf;
+ fileDataBuf.AppendFill( 0xFF, KSmsElemetaryFileRecordLength );
+
+ params.fileData.Append( fileDataBuf );
+
+ return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+ }
+ else
+ {
+ // Location is empty. Check next location
+ UiccDeleteAllSMSResp( KErrNone );
+ }
+ }
+ else
+ {
+ iMessageRouter->Complete( EMobilePhoneStoreDeleteAll, KErrNone );
+ }
}
else
{
@@ -2959,6 +3078,7 @@
OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_BUILDSMSSBUSERDATA, "CMmSmsMessHandler::BuildSmsSbUserData" );
TUint8 dataLengthInOctets( 0 );
+ TUint8 subblockLength( 0 );
// If data is 7-bit, then TP-UDL is integer representation of
// the number of septets within the TP-UD field
@@ -2980,19 +3100,23 @@
userDataBuf,
SMS_SB_USER_DATA,
EIsiSubBlockTypeId16Len16 );
- userDataBuf.Append( KSmsPadding );
+ userDataBuf.Append( KSmsPadding );
userDataBuf.Append( dataLengthInOctets );
- userDataBuf.Append( KSmsPadding );
- userDataBuf.Append( aTpUdl );
+ userDataBuf.Append( KSmsPadding );
+ userDataBuf.Append( aTpUdl );
userDataBuf.Append( dataBytes );
aIsiMsg.CopyData( aMsgOffset, userData.CompleteSubBlock() );
+ subblockLength = userDataBuf.Length();
+
TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbUserData. User data length in octets: %d", dataLengthInOctets );
TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbUserData. User data character count: %d", aTpUdl );
OstTraceExt2( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_BUILDSMSSBUSERDATA, "CMmSmsMessHandler::BuildSmsSbUserData;dataLengthInOctets=%hhu;aTpUdl=%hhu", dataLengthInOctets, aTpUdl );
-
- return dataLengthInOctets + 8; // 8 bytes sub block header data before data bytes
+TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbUserData. Length of subblock: %d", subblockLength );
+OstTraceExt1( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_BUILDSMSSBUSERDATA, "CMmSmsMessHandler::BuildSmsSbUserData;subblockLength=%hhu", subblockLength );
+
+ return subblockLength;
}
@@ -3069,6 +3193,7 @@
TInt CMmSmsMessHandler::ProcessUiccMsg(
TInt aTraId,
TInt aStatus,
+ TUint8 /*aDetails*/,
const TDesC8& aFileData )
{
TFLOGSTRING3("TSY:CMmSmsMessHandler::ProcessUiccMsg, aTraId: %d, status: %d", aTraId, aStatus );
@@ -3099,6 +3224,70 @@
GetNumOfEFSMSRecordsResp( aStatus, aFileData );
break;
}
+ case ETrIdDeleteSMS:
+ {
+ UiccDeleteSMSResp( aStatus );
+ break;
+ }
+ case ETrIdDeleteAllSMSs:
+ {
+ UiccDeleteAllSMSResp( aStatus );
+ break;
+ }
+ case ETrIdUpdateSMSStatusReadSMS:
+ {
+ UiccUpdateSMSStatusReadSMSResp( aStatus, aFileData );
+ break;
+ }
+ case ETrIdUpdateSMSStatusWriteSMS:
+ {
+ UiccUpdateSMSStatusWriteSMSResp( aStatus );
+ break;
+ }
+ case ETrIdGetSmspEntries:
+ {
+ // If status is OK, save the entry and then try to read next record
+ if ( UICC_STATUS_OK == aStatus )
+ {
+ // Store the entry to the list
+ ret = UiccStoreSmspEntry( aFileData );
+ }
+
+ // If the first record was tried to read, but UICC server returned
+ // error or data was invalid, error is completed to commontsy
+ if ( 1 == iSmspRecordNumber &&
+ ( UICC_STATUS_OK != aStatus || KErrNone != ret ) )
+ {
+ iMessageRouter->Complete(
+ EMobileSmsMessagingGetSmspListPhase1,
+ KErrNotFound );
+ // Reset internal array
+ iSmspListArray->ResetAndDestroy();
+ }
+ // At least one SMS entry was read and stored successfully
+ else if( UICC_STATUS_OK != aStatus || KErrNone != ret )
+ {
+ CMmDataPackage package;
+ package.PackData( iSmspListArray );
+ iMessageRouter->Complete(
+ EMobileSmsMessagingGetSmspListPhase1,
+ &package,
+ KErrNone );
+ // Reset internal array
+ iSmspListArray->ResetAndDestroy();
+ }
+ break;
+ }
+ case ETrIdWriteSmspEntry:
+ {
+ TInt error( KErrNone );
+ if ( UICC_STATUS_OK != aStatus )
+ {
+ error = KErrNotFound;
+ }
+ iMessageRouter->Complete( EMobileSmsMessagingStoreSmspList, error );
+ break;
+ }
default:
{
TFLOGSTRING("TSY:CMmSmsMessHandler::ProcessUiccMsg - unknown transaction ID" );
@@ -3287,8 +3476,8 @@
iSmsCache.Status() );
// it is possible that re-caching was done due to sim refresh.
-// iMessageRouter->GetPhoneMessHandler()->
-// SmsCachingCompleted( iSmsCache.Status() );
+ iMessageRouter->GetPhoneMessHandler()->
+ SmsCachingCompleted( iSmsCache.Status() );
// if cache is up and a message was received while cacheing then resume
if ( KErrNone == iSmsCache.Status() && iReceivedClass2ToBeReSent )
@@ -3637,9 +3826,8 @@
}
// -----------------------------------------------------------------------------
-// CMmSmsMessHandler::SimStSmsGetNumOfLocReq
-// Construct a SIM_ST_SMS_GET_NUM_OF_LOC_REQ ISI message
-// to the SIM Server
+// CMmSmsMessHandler::GetNumOfEFSMSRecords
+//
// -----------------------------------------------------------------------------
//
void CMmSmsMessHandler::GetNumOfEFSMSRecords( void )
@@ -3666,19 +3854,13 @@
TFLOGSTRING("TSY: CMmSmsMessHandler::GetNumOfEFSMSRecordsResp" );
OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_GETNUMOFEFSMSRECORDSRESP, "CMmSmsMessHandler::GetNumOfEFSMSRecordsResp;aStatus=%d;aFileData=%s", aStatus, aFileData );
- TInt offSet( 0 );
-
//Save number of SMS locations on SIM card
TInt smsNumOfLoc( 0 );
if ( KErrNone == aStatus )
{
- offSet = aFileData.Find( &KTagFCIFileDescriptor, 1 );
- if( offSet != KErrNotFound )
- {
- smsNumOfLoc =
- aFileData[offSet + UICC_FCI_EF_FDESC_OFFSET_NUM_ENTR];
- }
+ TFci fci( aFileData );
+ smsNumOfLoc = fci.GetNumberOfRecords();
}
// Continue with reading all sms entries from sim
@@ -3712,4 +3894,594 @@
}
}
+// -----------------------------------------------------------------------------
+// CMmSmsMessHandler::UiccDeleteSMSResp
+//
+// -----------------------------------------------------------------------------
+//
+void CMmSmsMessHandler::UiccDeleteSMSResp( TInt aStatus )
+ {
+TFLOGSTRING2("TSY: CMmSmsMessHandler::UiccDeleteSMSResp aStatus: %d", aStatus );
+OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_UICCDELETESMSRESP, "CMmSmsMessHandler::UiccDeleteSMSResp;aStatus=%d", aStatus );
+
+ // Create Package
+ CMmDataPackage package;
+
+ TInt error( CMmStaticUtility::UICCCSCauseToEpocError( aStatus ) );
+
+ if ( KErrNone == error )
+ {
+ iSmsCache.Delete();
+ }
+ iMessageRouter->Complete( EMobilePhoneStoreDelete, error );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMmSmsMessHandler::UiccDeleteAllSMSResp
+//
+// -----------------------------------------------------------------------------
+//
+void CMmSmsMessHandler::UiccDeleteAllSMSResp( TInt aStatus )
+ {
+TFLOGSTRING2("TSY: CMmSmsMessHandler::UiccDeleteSMSResp aStatus: %d", aStatus );
+OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCDELETEALLSMSRESP, "CMmSmsMessHandler::UiccDeleteAllSMSResp;aStatus=%d", aStatus );
+
+ // Create Package
+ CMmDataPackage package;
+
+ TInt error( CMmStaticUtility::UICCCSCauseToEpocError( aStatus ) );
+
+ // Delete SMS from SIM one by one and then all from cache.
+ if ( ( iRecordId < iSmsCache.TotalEntries() ) &&
+ ( KErrNone == error ) )
+ {
+ iRecordId++; // Next record
+ error = DeleteAllSms();
+
+ if ( KErrNone != error )
+ {
+ iMessageRouter->Complete( EMobilePhoneStoreDeleteAll, error );
+ }
+ }
+ else
+ {
+ iSmsCache.DeleteAll();
+ iMessageRouter->Complete( EMobilePhoneStoreDeleteAll, error );
+ }
+
+ }
+// -----------------------------------------------------------------------------
+// CMmSmsMessHandler::CheckSCTimestamp
+// Returns ETrue if the SC timestamp in this message is equal to
+// the client's timestamp in aScTime.
+// -----------------------------------------------------------------------------
+//
+TBool CMmSmsMessHandler::CheckSCTimestamp(
+ const RMobileSmsStore::TMobileGsmSmsEntryV1& aEntry,
+ const TTime& aScTime )
+ {
+TFLOGSTRING("TSY: CMmSmsMessHandler::CheckSCTimestamp");
+OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp" );
+ TBool matchFound( EFalse );
+
+ TInt offset( 1 ); // Message Reference position
+ TInt messageReference( aEntry.iMsgData[offset] );
+ // Destination address length is integer representation
+ // of the number of useful semi-octets of address field
+ messageReference = ( messageReference + 1 ) / 2;
+ offset += messageReference;
+ offset += 4; // Service Centre Time Stamp
+
+ TBuf8<KSmsScTimeStampMaxLength> scTimeStamp;
+ scTimeStamp = aEntry.iMsgData.Mid( offset, KSmsScTimeStampMaxLength );
+
+ // Convert from the semi-octet representation to decimals.
+ for ( TUint8 i ( 0 ); i < KSmsScTimeStampMaxLength; i++ )
+ {
+ TUint8 lowDigit( static_cast<TUint8>( (
+ scTimeStamp[i] & 0xf0 ) >> 4 ) );
+ TUint8 highDigit( static_cast<TUint8>( scTimeStamp[i] & 0xf ) );
+ scTimeStamp[i] = static_cast<TUint8>( (10 * highDigit) + lowDigit );
+ }
+
+ // Ignore this messsage if month or day are zero (should not happen)
+ if ( ( 0 == scTimeStamp[1] ) || ( 0 == scTimeStamp[2] ) )
+ {
+TFLOGSTRING("TSY:CMmSmsMessHandler::CheckSCTimestamp:Invalid timestamp found, ignored.");
+OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp, Invalid timestamp found, ignored" );
+ matchFound = ETrue;
+ }
+
+ if ( !matchFound )
+ {
+ // Construct a string of the form YYYYMMDD:HHMMSS
+ TBuf<15> timeString;
+ // This is the same way Symbian GSMU does it,
+ // see GSMU's method TSmsServiceCenterTimeStamp::DecodeL.
+ if ( scTimeStamp[0]>95 )
+ {
+ timeString.Append( _L( "19" ) );
+ }
+ else
+ {
+ timeString.Append( _L( "20" ) );
+ }
+ //two digits for year, month, day, hour, minute, second
+ _LIT( KDateFormat, "%02d" );
+ //year
+ timeString.AppendFormat( KDateFormat,scTimeStamp[0] );
+ //month, starting at 0
+ timeString.AppendFormat( KDateFormat,scTimeStamp[1]-1 );
+ //day, starting at 0
+ timeString.AppendFormat( KDateFormat,scTimeStamp[2]-1 );
+ timeString.Append( _L(":" ) );
+ //hour
+ timeString.AppendFormat( KDateFormat,scTimeStamp[3] );
+ //minute
+ timeString.AppendFormat( KDateFormat,scTimeStamp[4] );
+ //second
+ timeString.AppendFormat( KDateFormat,scTimeStamp[5] );
+
+ TTime simStoredTime( 0 );
+ TInt err( simStoredTime.Set( timeString ) );
+
+ if ( KErrNone == err )
+ {
+ // Handle the timezone difference. The timezone is found in the
+ // last byte of the SC timestamp buffer.
+ TUint8 simTimezoneDiffRaw( scTimeStamp[6] );
+ // Highest bit is the algebraic sign (0=positive, 1=negative).
+ // Timezone is defined in 'quarters of an hour', but we allow
+ // only whole numbers.
+ TInt8 simTimezoneSign( ( simTimezoneDiffRaw & 0x80 ) ? -1 : 1 );
+ TInt8 simTimezoneDiff( static_cast<TInt8>(
+ simTimezoneSign * ( simTimezoneDiffRaw & 0x7F) / 4 ) );
+ // Substract timezone difference
+ TTimeIntervalHours simTimezoneInterval( simTimezoneDiff );
+ simStoredTime -= simTimezoneInterval;
+
+#ifdef _DEBUG
+ // debug print
+ TDateTime dt = simStoredTime.DateTime();
+TFLOGSTRING("TSY:CMmSmsMessHandler::CheckSCTimestamp:Message stored on SIM:");
+OstTrace0( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp, Message stored on SIM:" );
+TFLOGSTRING2(" year=%d",dt.Year());
+OstTrace1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Year=%d", dt.Year() );
+TFLOGSTRING2(" month=%d",dt.Month()+1);
+OstTrace1( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Month=%d", ( dt.Month() + 1 ) );
+TFLOGSTRING2(" day=%d",dt.Day()+1);
+OstTrace1( TRACE_NORMAL, DUP5_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Day=%d", ( dt.Day() + 1 ) );
+TFLOGSTRING2(" hour=%d",dt.Hour());
+OstTrace1( TRACE_NORMAL, DUP6_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Hour=%d", dt.Hour() );
+TFLOGSTRING2(" minute=%d",dt.Minute());
+OstTrace1( TRACE_NORMAL, DUP7_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Minute=%d", dt.Minute() );
+TFLOGSTRING2(" second=%d",dt.Second());
+OstTrace1( TRACE_NORMAL, DUP8_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Second=%d", dt.Second() );
+TFLOGSTRING2(" timezone difference=%d",simTimezoneDiff);
+OstTraceExt1( TRACE_NORMAL, DUP9_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;simTimezoneDiff=%hhd", simTimezoneDiff );
+ dt = aScTime.DateTime();
+TFLOGSTRING("TSY:CMmSmsMessHandler::CheckSCTimestamp:Message opened on client side:");
+OstTrace0( TRACE_NORMAL, DUP10_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp, Message opened on client side:" );
+TFLOGSTRING2(" year=%d",dt.Year());
+OstTrace1( TRACE_NORMAL, DUP11_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Year=%d", ( dt.Year() + 1 ) );
+TFLOGSTRING2(" month=%d",dt.Month()+1);
+OstTrace1( TRACE_NORMAL, DUP12_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Month=%d", ( dt.Month() + 1 ) );
+TFLOGSTRING2(" day=%d",dt.Day()+1);
+OstTrace1( TRACE_NORMAL, DUP13_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Day=%d", ( dt.Day() + 1 ) );
+TFLOGSTRING2(" hour=%d",dt.Hour());
+OstTrace1( TRACE_NORMAL, DUP14_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Hour=%d", dt.Hour() );
+TFLOGSTRING2(" minute=%d",dt.Minute());
+OstTrace1( TRACE_NORMAL, DUP15_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Minute=%d", dt.Minute() );
+TFLOGSTRING2(" second=%d",dt.Second());
+OstTrace1( TRACE_NORMAL, DUP16_CMMSMSMESSHANDLER_CHECKSCTIMESTAMP, "CMmSmsMessHandler::CheckSCTimestamp;Second=%d", dt.Second() );
+ // debug print
+#endif // _DEBUG
+
+ if ( simStoredTime == aScTime )
+ {
+ matchFound = ETrue;
+ }
+ }
+ }
+
+ return matchFound;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMmSmsMessHandler::UiccUpdateSMSStatus
+// Write SMS to SIM
+// -----------------------------------------------------------------------------
+//
+TInt CMmSmsMessHandler::UiccUpdateSMSStatus(
+ const TUint8 aRecordId
+ )
+ {
+TFLOGSTRING2("TSY: CMmSmsMessHandler::UiccUpdateSMSStatusReq aRecordId: %d", aRecordId );
+OstTraceExt1( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCUPDATESMSSTATUS, "CMmSmsMessHandler::UiccUpdateSMSStatus;aRecordId=%hhu", aRecordId );
+
+ // Read parameters from SIM
+ // Set parameters for UICC_APPL_CMD_REQ message
+ iRecordId = aRecordId;
+ TUiccReadLinearFixed params;
+ params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+ params.trId = ETrIdUpdateSMSStatusReadSMS;
+ params.dataOffset = 0;
+ params.dataAmount = 0;
+ params.record = aRecordId;
+
+ params.fileId = KElemFileShortMessages;
+ params.fileIdSfi = UICC_SFI_NOT_PRESENT;
+ params.serviceType = UICC_APPL_READ_LINEAR_FIXED;
+
+ // File id path
+ params.filePath.Append( KMasterFileId >> 8 );
+ params.filePath.Append( KMasterFileId );
+ params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+ return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMmSmsMessHandler::UiccUpdateSMSStatusReadSMSResp
+//
+// -----------------------------------------------------------------------------
+//
+void CMmSmsMessHandler::UiccUpdateSMSStatusReadSMSResp(
+ TInt aStatus,
+ const TDesC8& aFileData )
+ {
+TFLOGSTRING("TSY: CMmSmsMessHandler::UiccReadSMSResp" );
+OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCUPDATESMSSTATUSREADSMSRESP, "CMmSmsMessHandler::UiccUpdateSMSStatusReadSMSResp" );
+
+ if ( KErrNone == aStatus )
+ {
+ if ( 0 != aFileData.Length() )
+ {
+ // Set parameters for UICC_APPL_CMD_REQ message
+ TUiccWriteLinearFixed params;
+ params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+ params.trId = ETrIdUpdateSMSStatusWriteSMS;
+ params.dataOffset = 0;
+ params.dataAmount = 0;
+ params.record = iRecordId;
+
+ params.fileId = KElemFileShortMessages;
+ params.fileIdSfi = UICC_SFI_NOT_PRESENT;
+ params.serviceType = UICC_APPL_UPDATE_LINEAR_FIXED;
+
+ // File id path
+ params.filePath.Append( KMasterFileId >> 8 );
+ params.filePath.Append( KMasterFileId );
+ params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+ // Update status as read
+ // File data to be updated.
+ TBuf8<KSmsElemetaryFileRecordLength> fileDataBuf;
+ fileDataBuf = aFileData.Left( aFileData.Length() );
+ fileDataBuf[0] = KSimSmsMtRead;
+
+ TInt unfilledLength( fileDataBuf.MaxLength() - aFileData.Length() );
+ // Fill unused fields with FF
+ if ( 0 < unfilledLength )
+ {
+ fileDataBuf.AppendFill( 0xFF, unfilledLength );
+ }
+
+ params.fileData.Append( fileDataBuf );
+
+ TInt ret( iMmUiccMessHandler->CreateUiccApplCmdReq( params ) );
+
+ if ( KErrNone != ret )
+ {
+ iMessageRouter->Complete(
+ ECustomSetSimMessageStatusReadIPC,
+ ret );
+ }
+ }
+ }
+ else
+ {
+ iMessageRouter->Complete(
+ ECustomSetSimMessageStatusReadIPC,
+ CMmStaticUtility::UICCCSCauseToEpocError( aStatus ) );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMmSmsMessHandler::UiccUpdateSMSStatusWriteSMSResp
+//
+// -----------------------------------------------------------------------------
+//
+void CMmSmsMessHandler::UiccUpdateSMSStatusWriteSMSResp( TInt aStatus )
+ {
+TFLOGSTRING2("TSY: CMmSmsMessHandler::UiccUpdateSMSStatusReadSMSResp aStatus: %d", aStatus );
+OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_UICCUPDATESMSSTATUSREADSMSRESP, "CMmSmsMessHandler::UiccUpdateSMSStatusReadSMSResp;aStatus=%d", aStatus );
+
+ iMessageRouter->Complete(
+ ECustomSetSimMessageStatusReadIPC,
+ CMmStaticUtility::UICCCSCauseToEpocError( aStatus ) );
+
+ // Update the same flag also in TSY's cache.
+ if ( KErrNone == aStatus )
+ {
+ iSmsCache.SetStorageStatus( iRecordId, RMobileSmsStore::EStoredMessageRead );
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMmSmsMessHandler::UiccGetSmspEntryReq
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMmSmsMessHandler::UiccGetSmspEntryReq()
+ {
+TFLOGSTRING("TSY: CMmSmsMessHandler::UiccGetSmspEntryReq" );
+OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCREADNUMOFSMSPENTRIES, "CMmSmsMessHandler::UiccGetSmspEntryReq" );
+
+ // Set parameters for UICC_APPL_CMD_REQ message
+ TUiccReadLinearFixed params;
+ params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+ params.trId = ETrIdGetSmspEntries;
+ params.dataOffset = 0;
+ params.dataAmount = 0;
+ params.record = iSmspRecordNumber;
+ params.fileId = KElemFileSmsParams;
+ params.fileIdSfi = UICC_SFI_NOT_PRESENT;
+ params.serviceType = UICC_APPL_READ_LINEAR_FIXED;
+
+ // File id path
+ params.filePath.Append( KMasterFileId >> 8 );
+ params.filePath.Append( KMasterFileId );
+ params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+ return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMmSmsMessHandler::UiccStoreSmspEntry
+//
+// -----------------------------------------------------------------------------
+//
+TInt CMmSmsMessHandler::UiccStoreSmspEntry( const TDesC8& aFileData )
+ {
+TFLOGSTRING("TSY: CMmSmsMessHandler::UiccStoreSmspEntry" );
+OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCSTORESMSPENTRY, "CMmSmsMessHandler::UiccStoreSmspEntry" );
+
+ TInt ret( KErrNone );
+ TInt dataLength( aFileData.Length() );
+ TPtrC8 data( KNullDesC8 );
+ TSmsParameters* smsParam = new ( ELeave ) TSmsParameters();
+ CleanupStack::PushL( smsParam );
+
+ // SMS parameters are located in EF smsp, see 3GPP TS 31.102
+ // V8.3.0 chapter 4.2.27 EFSMSP (Short message service parameters)
+
+ // Alpha identifier is optional. Check if it exists.
+ if ( KSmsMandatoryParamsLength < dataLength )
+ {
+ // Copy mandatory fields to different buffer for later use
+ data.Set( aFileData.Right( KSmsMandatoryParamsLength ) );
+ smsParam->iAlphaTagPresent = ETrue;
+
+ // Alpha identifier length
+ TInt alphaLength( dataLength - KSmsMandatoryParamsLength );
+ if ( RMobileSmsMessaging::KMaxSmspTextSize < alphaLength )
+ {
+ alphaLength = RMobileSmsMessaging::KMaxSmspTextSize;
+ }
+
+ // Copy alpha identifier data as it is in SIM elementary file
+ TBuf8<RMobileSmsMessaging::KMaxSmspTextSize> alphaIdentifier;
+ alphaIdentifier.Copy( aFileData.Left( alphaLength ) );
+
+ // Coding of alpha identifier may be 7-bit default of one of UCS2 code
+ // options. At first convert data to 16-bit format
+ TBuf8<RMobileSmsMessaging::KMaxSmspTextSize> alphaIdentifierOutput;
+ CMmStaticUtility::ConvertGsmDataToUcs2(
+ alphaIdentifier,
+ alphaIdentifier.Length(),
+ alphaIdentifierOutput );
+
+ // Convert to 16-bit UNICODE string and copy to SMS parameters buffer
+ TBuf16<RMobileSmsMessaging::KMaxSmspTextSize> alphaBuf;
+ TIsiUtility::CopyFromBigEndian( alphaIdentifierOutput, alphaBuf );
+ smsParam->iAlphaTagData.Copy( alphaBuf );
+ }
+ // Only mandatory 28 bytes are included, no alpha identifier
+ else if ( KSmsMandatoryParamsLength == dataLength )
+ {
+ smsParam->iAlphaTagPresent = EFalse;
+ // Copy all the data
+ data.Set( aFileData );
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+
+ if ( KErrNone == ret )
+ {
+ // Parameters indicator.
+ // In SIM card bit value "0" means that parameter is present,
+ // in S60 vice versa
+ TUint8 paramIndicators( data[0] );
+ paramIndicators = ~paramIndicators;
+ paramIndicators &= KSmsGsmParametersIndMask; // Mask 5 LSB
+ smsParam->iParameterIndicator = paramIndicators;
+
+ // Location where SMS parameters in EFsms were fetched
+ smsParam->iLocationNumber = iSmspRecordNumber;
+
+ // Service center address
+ if ( paramIndicators & KServiceCentreAddress )
+ {
+ TBuf8<KSmsMaxAddressLength>scAddress( data. Mid(
+ KSmsParamsScAddressOffset, KSmsMaxAddressLength ) );
+ CMmSmsGsmAddress::GsmConv0411AddrToUnicode(
+ smsParam->iServiceCenterAddress,
+ scAddress,
+ smsParam->iMobileScTON,
+ smsParam->iMobileScNPI );
+ }
+
+ // Destination address
+ if ( paramIndicators & KDestinationAddress )
+ {
+ TBuf8<KSmsMaxAddressLength>destAddress( data.Mid(
+ KSmsParamsDestAddressOffset, KSmsMaxAddressLength ) );
+ CMmSmsGsmAddress::GsmConv0340AddrToUnicode(
+ smsParam->iDestinationAddress,
+ destAddress,
+ smsParam->iMobileDeTON,
+ smsParam->iMobileDeNPI );
+ }
+
+ // Protocol ID
+ if ( paramIndicators & KProtocolID )
+ {
+ smsParam->iProtocolId = data[KSmsParamsProtocolIdOffset];
+ }
+
+ // Data coding scheme
+ if ( paramIndicators & KDataCodingScheme )
+ {
+ smsParam->iDataCodingScheme = data[KSmsParamsDcsOffset];
+ }
+
+ // Validity period
+ if ( paramIndicators & KValidityPeriod )
+ {
+ smsParam->iValidityPeriod = data[KSmsParamsValidityPeriodOffset];
+ }
+
+ // Add this parameter set to array
+ iSmspListArray->AppendL( smsParam );
+ // Read the next entry
+ iSmspRecordNumber++;
+ ret = UiccGetSmspEntryReq();
+ }
+ // Don't reset struct because it may be stored to CArrayPtrFlat.
+ // All structs will be reseted when request is completed.
+ CleanupStack::Pop( smsParam );
+ return ret;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMmSmsMessHandler::UiccSmsUpdateParameterReq
+// -----------------------------------------------------------------------------
+//
+TInt CMmSmsMessHandler::UiccSmsUpdateParameterReq(
+ const CMmDataPackage* aDataPackage )
+ {
+TFLOGSTRING("TSY: CMmSmsMessHandler::UiccSmsUpdateParameterReq");
+OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_UICCSTORESMSPENTRY, "CMmSmsMessHandler::UiccStoreSmspEntry" );
+
+ RMobileSmsMessaging::TMobileSmspEntryV1* smsParameters;
+ // Unpack data
+ aDataPackage->UnPackData( &smsParameters );
+
+ // Buffer for all the file data to be written to UICC
+ // (possible alpha tag + params )
+ TBuf8<KSmsMandatoryParamsLength + KSizeOfAlphaTag> smspBuffer;
+
+ // Check if there is alpha tag
+ TInt alphaTagLength( smsParameters->iText.Length() );
+ // Buffer for alpha tag
+ if ( 0 < alphaTagLength )
+ {
+ // Temporary buffer for alpha tag
+ TBuf8<KSizeOfAlphaTag> alphaTagData;
+ TIsiUtility::CopyToBigEndian( smsParameters->iText, alphaTagData );
+ smspBuffer.Append( 0x80 ); // First byte 0x80 means 16-bit UCS coding
+ smspBuffer.Append( alphaTagData );
+ }
+
+ // Temporary buffer for mandatory data, filled by FF (unused bytes)
+ TBuf8<KSmsMandatoryParamsLength> paramsData;
+ paramsData.Fill( 0xFF, KSmsMandatoryParamsLength );
+
+ // Fill SMS parameters to data buffer ( see 3GPP TS 31.102 V8.3.0
+ // 4.2.27 EFSMSP (Short message service parameters). Unused parameters
+ // are filled by 0xFF
+
+ // Parameter indicator
+ TUint8 paramInd( static_cast<TUint8>( smsParameters->iValidParams ) );
+ paramsData[KSmsParamsParamIndicatorOffset] = paramInd;
+
+ // Destination address
+ if ( KDestinationAddress & paramInd )
+ {
+ TBuf8<KSmsMaxAddressLength> deAddr;
+ // Fill address by 0x00 at first
+ BuildDeAddress( smsParameters->iDestination, deAddr );
+ // Add address data to buffer
+ paramsData.Replace(
+ KSmsParamsDestAddressOffset,
+ deAddr.Length(),
+ deAddr );
+ }
+
+ // Service center address
+ if ( KServiceCentreAddress & paramInd )
+ {
+ TBuf8<KSmsMaxAddressLength> scAddr;
+ // Fill address by 0x00 at first
+ BuildScAddress( smsParameters->iServiceCentre, scAddr );
+ // Add address data to buffer
+ paramsData.Replace(
+ KSmsParamsScAddressOffset,
+ scAddr.Length(),
+ scAddr );
+ }
+
+ // Protocol ID
+ if ( KProtocolID & paramInd )
+ {
+ paramsData[KSmsParamsProtocolIdOffset] = smsParameters->iProtocolId;
+ }
+
+ // Data coding scheme
+ if ( KDataCodingScheme & paramInd )
+ {
+ paramsData[KSmsParamsDcsOffset] = smsParameters->iDcs;
+ }
+
+ // If validity period is valid, set value
+ if ( KValidityPeriod & paramInd )
+ {
+ paramsData[KSmsParamsValidityPeriodOffset] =
+ smsParameters->iValidityPeriod;
+ }
+
+ smspBuffer.Append( paramsData );
+
+ // Set parameters for UICC_APPL_CMD_REQ message
+ TUiccWriteLinearFixed params;
+ params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+ params.trId = ETrIdWriteSmspEntry;
+ params.dataOffset = 0;
+ params.dataAmount = 0;
+ params.record = smsParameters->iIndex;
+
+ params.fileId = KElemFileSmsParams;
+ params.fileIdSfi = UICC_SFI_NOT_PRESENT;
+ params.serviceType = UICC_APPL_UPDATE_LINEAR_FIXED;
+
+ // File id path
+ params.filePath.Append( KMasterFileId >> 8 );
+ params.filePath.Append( KMasterFileId );
+ params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+ // File data
+ params.fileData.Append( smspBuffer );
+
+ return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+ }
+
// End of File