messagingappbase/smsmtm/clientmtm/src/SMUTHDR.CPP
changeset 25 84d9eb65b26f
parent 23 238255e8b033
child 27 e4592d119491
child 37 518b245aa84c
child 79 2981cb3aa489
equal deleted inserted replaced
23:238255e8b033 25:84d9eb65b26f
     1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <smuthdr.h>
       
    17 #include <csmsemailfields.h>
       
    18 #include <gsmuieoperations.h>
       
    19 
       
    20 #include <gsmumsg.h>
       
    21 #include <msvstore.h>	
       
    22 #include <cntdb.h>
       
    23 #include <gsmunonieoperations.h>
       
    24 #include <gsmuelem.h>
       
    25 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS  
       
    26 #include <tmsvsmsentry.h>
       
    27 #endif
       
    28 
       
    29 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
    30 #include <msvrcpt.h> 
       
    31 #endif
       
    32 	
       
    33 const TUid KUidMsvSMSHeaderStream		= {0x10001834};
       
    34 const TInt16 KMsvSmsHeaderVersion		= 1;
       
    35 const TInt KSmcmRecipientsGranularity	= 8;
       
    36 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
    37 _LIT16(KComma, ",");
       
    38 _LIT16(KDelimiter, ";");
       
    39 #endif
       
    40 
       
    41 /** 
       
    42 Allocates and constructs a new CSmsHeader object.
       
    43 
       
    44 Use this function to create a new SMS-SUBMIT, SMS-COMMAND, SMS-DELIVER or 
       
    45 SMS-STATUS-REPORT type message.
       
    46 
       
    47 @param	aType
       
    48 The Protocol Data Unit (PDU) type for the SMS message.
       
    49 
       
    50 @param	aText
       
    51 The message text.
       
    52 
       
    53 @return
       
    54 A new CSmsHeader object.
       
    55 */
       
    56 EXPORT_C CSmsHeader* CSmsHeader::NewL(CSmsPDU::TSmsPDUType aType, CEditableText& aText)
       
    57 	{
       
    58 	CSmsHeader* self = new(ELeave) CSmsHeader();
       
    59 	CleanupStack::PushL(self);
       
    60 	self->ConstructL(aType, aText);
       
    61 	CleanupStack::Pop(self);
       
    62 	return self;
       
    63 	}
       
    64 	
       
    65 /** 
       
    66 Allocates and constructs a new CSmsHeader object.
       
    67 
       
    68 Use this function to create a new SMS-SUBMIT, SMS-COMMAND, SMS-DELIVER or 
       
    69 SMS-STATUS-REPORT type message. This version uses a previously connected
       
    70 file server session handle.
       
    71 
       
    72 @param	aType
       
    73 The Protocol Data Unit (PDU) type for the SMS message.
       
    74 
       
    75 @param	aText
       
    76 The message text.
       
    77 
       
    78 @param aFs
       
    79 Handle to an open file server session. CSmsHeader will not close the file session.
       
    80 
       
    81 @return
       
    82 A new CSmsHeader object.
       
    83 */
       
    84 EXPORT_C CSmsHeader* CSmsHeader::NewL(CSmsPDU::TSmsPDUType aType, CEditableText& aText, RFs& aFs)
       
    85 	{
       
    86 	CSmsHeader* self = new(ELeave) CSmsHeader();
       
    87 	CleanupStack::PushL(self);
       
    88 	self->ConstructL(aType, aText, aFs);
       
    89 	CleanupStack::Pop(self);
       
    90 	return self;
       
    91 	}
       
    92 
       
    93 /** 
       
    94 Allocates and constructs a new CSmsHeader object.
       
    95 
       
    96 Use this function to create a new SMS-DELIVER type message.
       
    97 
       
    98 @param	aMessage
       
    99 The SMS message encapsulation from the SMS stack.
       
   100 
       
   101 @return
       
   102 A new CSmsHeader object.
       
   103 */
       
   104 EXPORT_C CSmsHeader* CSmsHeader::NewL(CSmsMessage* aMessage)
       
   105 	{
       
   106 	CSmsHeader* self = new(ELeave) CSmsHeader(aMessage);
       
   107 	CleanupStack::PushL(self);
       
   108 	self->ConstructL();
       
   109 	CleanupStack::Pop(self);
       
   110 	return self;
       
   111 	}
       
   112 
       
   113 /**
       
   114 Destructor.
       
   115 */
       
   116 EXPORT_C CSmsHeader::~CSmsHeader()
       
   117 	{
       
   118 	iRecipients.ResetAndDestroy();
       
   119 	delete iMessage;
       
   120 	delete iEmailFields;
       
   121 	if(iCloseFs)
       
   122 		{
       
   123 		iFs.Close();
       
   124 		}
       
   125 	}
       
   126 
       
   127 /** 
       
   128 Sets the SMS message settings for the message.
       
   129 
       
   130 This can only be used on SMS-SUBMIT, SMS-COMMAND, SMS-DELIVER or SMS-STATUS-REPORT
       
   131 type messages.
       
   132 
       
   133 NOTE - if this is an Email over SMS message then the PID of is not changed. The
       
   134 PID would have been set correctly when the email fields were set.
       
   135 
       
   136 @param	aSmsSettings
       
   137 The SMS message settings for the message
       
   138 
       
   139 @leave	KErrNotSupported
       
   140 The message PDU type was not supported, or the message conversion value was not
       
   141 supported.
       
   142 
       
   143 @panic	SMCM	0
       
   144 The message PDU is not supported (debug only).
       
   145 */
       
   146 EXPORT_C void CSmsHeader::SetSmsSettingsL(const CSmsMessageSettings& aSmsSettings)
       
   147 	{
       
   148 	__ASSERT_DEBUG( (Type()==CSmsPDU::ESmsSubmit) || (Type()==CSmsPDU::ESmsDeliver) || (Type()==CSmsPDU::ESmsStatusReport) || (Type()==CSmsPDU::ESmsCommand), Panic(ESmutPanicUnsupportedMsgType)); 
       
   149 
       
   150 	switch(Type())
       
   151 		{
       
   152 		case(CSmsPDU::ESmsSubmit):
       
   153 			{
       
   154 			Submit().SetRejectDuplicates(aSmsSettings.RejectDuplicate());
       
   155 			Submit().SetReplyPath(aSmsSettings.ReplyPath());
       
   156 			
       
   157 			//Check if delivery report for the last segment only is required . 
       
   158 			if(aSmsSettings.LastSegmentDeliveryReport())
       
   159 				{
       
   160 				CSmsTPSRROperations& tpSRROperations = static_cast<CSmsTPSRROperations&>(iMessage->GetOperationsForNonIEL(ESmsTPSRRParameter));
       
   161 				tpSRROperations.SetSchemeL();
       
   162 				tpSRROperations.SetLastSegmentStatusReportL(ETrue);
       
   163 				}
       
   164 			else
       
   165 				{
       
   166 				Submit().SetStatusReportRequest(aSmsSettings.DeliveryReport());	
       
   167 				}
       
   168 			Submit().SetValidityPeriod(aSmsSettings.ValidityPeriod());
       
   169 			Submit().SetValidityPeriodFormat(aSmsSettings.ValidityPeriodFormat());
       
   170 			break;
       
   171 			}
       
   172 		case(CSmsPDU::ESmsCommand):
       
   173 			{
       
   174 			Command().SetStatusReportRequest(aSmsSettings.DeliveryReport());
       
   175 			break;
       
   176 			}
       
   177 		case(CSmsPDU::ESmsDeliver):
       
   178 		case(CSmsPDU::ESmsStatusReport):
       
   179 			break;
       
   180 		default:
       
   181 			{			
       
   182 			User::Leave(KErrNotSupported);
       
   183 			break;
       
   184 			}
       
   185 		};
       
   186 
       
   187 	if (Message().TextPresent())
       
   188 		SetCanConcatenate(aSmsSettings.CanConcatenate());
       
   189 
       
   190 	CSmsPDU& pdu=Message().SmsPDU();
       
   191 	if (pdu.DataCodingSchemePresent())
       
   192 		pdu.SetAlphabet(aSmsSettings.CharacterSet());
       
   193 	if (pdu.ProtocolIdentifierPresent() && iEmailFields->Length() == 0 )
       
   194 		{
       
   195 		// The email fields object for this message is empty - therefore the
       
   196 		// PID can be set. With a non-empty email fields object the PID would
       
   197 		// have been set for interworking with email and MUST not be changed.
       
   198 		pdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDTelematicInterworking);
       
   199 
       
   200 		// MessageConversion
       
   201 		switch(aSmsSettings.MessageConversion())
       
   202 			{
       
   203 			case(ESmsConvPIDNone):
       
   204 				{
       
   205 				pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsNoTelematicDevice);
       
   206 				break;
       
   207 				}
       
   208 			case ESmsConvFax:
       
   209 			case ESmsConvX400:
       
   210 			case ESmsConvPaging:
       
   211 			case ESmsConvMail:
       
   212 			case ESmsConvErmes:
       
   213 			case ESmsConvSpeech:
       
   214 				{
       
   215 				pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsTelematicDevice);
       
   216 				pdu.SetTelematicDeviceType((TSmsProtocolIdentifier::TSmsTelematicDeviceType) aSmsSettings.MessageConversion());
       
   217 				break;
       
   218 				}
       
   219 			default:
       
   220 				{
       
   221 				User::Leave(KErrNotSupported);
       
   222 				break;
       
   223 				}
       
   224 			}; 
       
   225 		}
       
   226 	}
       
   227 
       
   228 /** 
       
   229 Gets the SMS message settings for the message.
       
   230 
       
   231 This can only be used on SMS-SUBMIT type messages.
       
   232 
       
   233 @param	aSmsSettings
       
   234 The output argument with the SMS message settings.
       
   235 
       
   236 @leave	KErrNotSupoprted
       
   237 The Telematic Device type is not supported.
       
   238 
       
   239 @panic	SMCM	0
       
   240 The message PDU is not supported (debug only).
       
   241 */
       
   242 EXPORT_C void CSmsHeader::GetSmsSettingsL(CSmsMessageSettings& aSmsSettings) const
       
   243 	{
       
   244 	__ASSERT_DEBUG( Type()==CSmsPDU::ESmsSubmit, Panic(ESmutPanicUnsupportedMsgType)); 
       
   245 	switch(Type())
       
   246 		{
       
   247 		case(CSmsPDU::ESmsSubmit):
       
   248 			{
       
   249 			aSmsSettings.SetRejectDuplicate(Submit().RejectDuplicates());
       
   250 			aSmsSettings.SetReplyPath(Submit().ReplyPath());
       
   251 			TSmsStatusReportScheme scheme = iMessage->Scheme();
       
   252 			if (scheme == ETPSRRScheme)	
       
   253 				{
       
   254 				aSmsSettings.SetLastSegmentDeliveryReport(ETrue);
       
   255 				}
       
   256 			else
       
   257 				{
       
   258 				aSmsSettings.SetDeliveryReport(Submit().StatusReportRequest());
       
   259 				}
       
   260 			aSmsSettings.SetValidityPeriod(Submit().ValidityPeriod());
       
   261 			aSmsSettings.SetValidityPeriodFormat(Submit().ValidityPeriodFormat());
       
   262 			aSmsSettings.SetCharacterSet(Submit().Alphabet());
       
   263 		
       
   264 			if (iMessage->SmsPDU().PIDType() == TSmsProtocolIdentifier::ESmsPIDTelematicInterworking)
       
   265 				{
       
   266 				if (iMessage->SmsPDU().TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsNoTelematicDevice)
       
   267 					{
       
   268 					aSmsSettings.SetMessageConversion(ESmsConvPIDNone);
       
   269 					}
       
   270 				else //if (iMessage->SmsPDU().TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsTelematicDevice)
       
   271 					{
       
   272 					switch (iMessage->SmsPDU().TelematicDeviceType())
       
   273 						{
       
   274 						case TSmsProtocolIdentifier::ESmsGroup3TeleFax:
       
   275 						case TSmsProtocolIdentifier::ESmsX400MessageHandlingSystem:
       
   276 						case TSmsProtocolIdentifier::ESmsNationalPagingSystem:
       
   277 						case TSmsProtocolIdentifier::ESmsInternetElectronicMail:
       
   278 						case TSmsProtocolIdentifier::ESmsERMES:
       
   279 						case TSmsProtocolIdentifier::ESmsVoiceTelephone:
       
   280 							aSmsSettings.SetMessageConversion((TSmsPIDConversion) iMessage->SmsPDU().TelematicDeviceType());
       
   281 							break;
       
   282 						default:
       
   283 							User::Leave(KErrNotSupported);
       
   284 							break;
       
   285 						}
       
   286 					}
       
   287 				}
       
   288 
       
   289 			aSmsSettings.SetCanConcatenate(CanConcatenate());
       
   290 			break;
       
   291 			}
       
   292 		default:
       
   293 			{
       
   294 			break;
       
   295 			}
       
   296 		}
       
   297 	}
       
   298 	
       
   299 /**
       
   300 Sets the email fields for the message.
       
   301 
       
   302 If the supplied email fields is not empty then the PID of the PDU of the message
       
   303 is set for interworking with email.
       
   304 
       
   305 If the supplied email fields is empty and the PID of the PDU of the message is 
       
   306 set for interworking with email then the PID is set to the default value that
       
   307 indicates no telematic device. If the PID was not set for interworking with 
       
   308 email then it is left unchanged.
       
   309 
       
   310 @param	aEmailFields
       
   311 The email fields object. A copy is made of this object.
       
   312 */	
       
   313 EXPORT_C void CSmsHeader::SetEmailFieldsL(const CSmsEmailFields& aEmailFields)
       
   314 	{
       
   315 	__ASSERT_DEBUG( Type()==CSmsPDU::ESmsSubmit, Panic(ESmutPanicUnsupportedMsgType)); 
       
   316 
       
   317 	CSmsEmailFields* temp = CSmsEmailFields::NewL(aEmailFields);
       
   318 	delete iEmailFields;
       
   319 	iEmailFields = temp;
       
   320 	
       
   321 	CSmsPDU& pdu = Message().SmsPDU();
       
   322 	if( pdu.ProtocolIdentifierPresent() )
       
   323 		{
       
   324 		if( iEmailFields->Length() > 0 )
       
   325 			{
       
   326 			// Set the PID for interworking with email.
       
   327 			pdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDTelematicInterworking);
       
   328 			pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsTelematicDevice);
       
   329 			pdu.SetTelematicDeviceType(TSmsProtocolIdentifier::ESmsInternetElectronicMail);
       
   330 			}
       
   331 		else
       
   332 			{
       
   333 			// The email fields are empty - if the PID is set for interworking
       
   334 			// with email, set to indicate no telematic device.
       
   335 			if(	pdu.PIDType() == TSmsProtocolIdentifier::ESmsPIDTelematicInterworking &&
       
   336 				pdu.TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsTelematicDevice &&
       
   337 				pdu.TelematicDeviceType() == TSmsProtocolIdentifier::ESmsInternetElectronicMail )
       
   338 				{
       
   339 				pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsNoTelematicDevice);
       
   340 				}
       
   341 			}
       
   342 		}
       
   343 	}
       
   344 	
       
   345 /**
       
   346 Sets the email fields for a reply message.
       
   347 
       
   348 The address field is copied from the specified email fields. The subject field 
       
   349 is formatted according to the specified subject format using the subject from 
       
   350 the specified email fields.
       
   351 
       
   352 The PID of the PDU of the message is set for interworking with email.
       
   353 
       
   354 @param	aEmailFields
       
   355 The email fields object.
       
   356 
       
   357 @param	aReplySubjectFormat
       
   358 The format of the subject field.
       
   359 
       
   360 @internalComponent
       
   361 */
       
   362 void CSmsHeader::SetReplyEmailFieldsL(const CSmsEmailFields& aEmailFields, const TDesC& aReplySubjectFormat)
       
   363 	{
       
   364 	// Create the reply email fields - copy address and then format the subject,
       
   365 	// if one exists according to the reply prefix.
       
   366 	CSmsEmailFields* temp = CSmsEmailFields::NewL();
       
   367 	CleanupStack::PushL(temp);
       
   368 	temp->AddAddressL(aEmailFields.Addresses().MdcaPoint(0));
       
   369 	
       
   370 	SetEmailReplyForwardSubjectL(temp, aEmailFields.Subject(), aReplySubjectFormat);
       
   371 
       
   372 	CleanupStack::Pop(temp);
       
   373 	delete iEmailFields;
       
   374 	iEmailFields = temp;
       
   375 
       
   376 	// Set the PID for interworking with email.
       
   377 	CSmsPDU& pdu = Message().SmsPDU();
       
   378 	if( pdu.ProtocolIdentifierPresent() )
       
   379 		{
       
   380 		pdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDTelematicInterworking);
       
   381 		pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsTelematicDevice);
       
   382 		pdu.SetTelematicDeviceType(TSmsProtocolIdentifier::ESmsInternetElectronicMail);
       
   383 		}
       
   384 	}
       
   385 
       
   386 /**
       
   387 Sets the email fields for a forward message.
       
   388 
       
   389 The address field is left empty. The subject field is formatted according to the
       
   390 specified subject format using the subject from the specified email fields.
       
   391 
       
   392 The PID of the PDU of the message is set for interworking with email.
       
   393 
       
   394 @param	aEmailFields
       
   395 The email fields object.
       
   396 
       
   397 @param	aForwardSubjectFormat
       
   398 The format of the subject field.
       
   399 
       
   400 @internalComponent
       
   401 */
       
   402 void CSmsHeader::SetForwardEmailFieldsL(const CSmsEmailFields& aEmailFields, const TDesC& aForwardSubjectFormat)
       
   403 	{
       
   404 	// Create the reply email fields - copy address and then format the subject,
       
   405 	// if one exists according to the reply prefix.
       
   406 	CSmsEmailFields* temp = CSmsEmailFields::NewL();
       
   407 	CleanupStack::PushL(temp);
       
   408 	
       
   409 	SetEmailReplyForwardSubjectL(temp, aEmailFields.Subject(), aForwardSubjectFormat);
       
   410 
       
   411 	CleanupStack::Pop(temp);
       
   412 	delete iEmailFields;
       
   413 	iEmailFields = temp;
       
   414 
       
   415 	// Set the PID for interworking with email.
       
   416 	CSmsPDU& pdu = Message().SmsPDU();
       
   417 	if( pdu.ProtocolIdentifierPresent() )
       
   418 		{
       
   419 		pdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDTelematicInterworking);
       
   420 		pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsTelematicDevice);
       
   421 		pdu.SetTelematicDeviceType(TSmsProtocolIdentifier::ESmsInternetElectronicMail);
       
   422 		}
       
   423 	}
       
   424 	
       
   425 void CSmsHeader::SetEmailReplyForwardSubjectL(CSmsEmailFields* aEmailFields, const TDesC& aSubject, const TDesC& aSubjectFormat)
       
   426 	{
       
   427 	TInt length = aSubject.Length();
       
   428 	if( length > 0 )
       
   429 		{
       
   430 		// Prevent a chain of the format string appearing in the subject - check
       
   431 		// to see if the format string is already the prefix of the subject.
       
   432 		TInt formatPosInSubject = KErrNotFound;
       
   433 
       
   434 		_LIT(KFormatStringSpecifier, "%S");
       
   435 		TInt formatPos = aSubjectFormat.Find(KFormatStringSpecifier);
       
   436 		if( formatPos > 0 )
       
   437 			{
       
   438 			// Look in current subject for the format string - avoid the '%'.
       
   439 			formatPosInSubject = aSubject.FindF(aSubjectFormat.Left(formatPos - 1));
       
   440 			}
       
   441 		
       
   442 		// Need to format the string if the format string is not at the start of
       
   443 		// the current subject.
       
   444 		if( formatPosInSubject != 0 )
       
   445 			{
       
   446 			// Create a buffer large enough to hold re-formated subject - need
       
   447 			// to subtract two from the prefix length (the %S).
       
   448 			length += aSubjectFormat.Length() - 2;
       
   449 			HBufC* buf = HBufC::NewLC(length);
       
   450 			TPtr ptr(buf->Des());
       
   451 			
       
   452 			// Format the reply subject and set in the email fields.
       
   453 			ptr.Format(aSubjectFormat, &aSubject);
       
   454 			aEmailFields->SetSubjectL(*buf);
       
   455 			
       
   456 			CleanupStack::PopAndDestroy(buf);
       
   457 			}
       
   458 		else
       
   459 			{
       
   460 			// Subject already contains the format string - use it.
       
   461 			aEmailFields->SetSubjectL(aSubject);
       
   462 			}
       
   463 		}
       
   464 	}
       
   465 	
       
   466 /**
       
   467 The email fields object for this message.
       
   468 
       
   469 @return
       
   470 The email fields object for this message.
       
   471 */	
       
   472 EXPORT_C const CSmsEmailFields& CSmsHeader::EmailFields() const
       
   473 	{
       
   474 	return *iEmailFields;
       
   475 	}
       
   476 
       
   477 /** 
       
   478 Internalises the object from the specified stream.
       
   479 
       
   480 @param	aStream
       
   481 The stream to be read from.
       
   482 */
       
   483 EXPORT_C void CSmsHeader::InternalizeL(RMsvReadStream& aStream)
       
   484 	{
       
   485 #if (!defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   486 
       
   487 	aStream.ReadInt16L(); //version. Not used yet
       
   488 	
       
   489 	iRecipients.ResetAndDestroy();
       
   490 	TInt count=aStream.ReadInt32L();
       
   491 	while(count--)
       
   492 		{
       
   493 		CSmsNumber* recipient=CSmsNumber::NewL();  
       
   494 		CleanupStack::PushL(recipient);
       
   495 		recipient->InternalizeL(aStream);
       
   496 		iRecipients.AppendL(recipient);
       
   497 		CleanupStack::Pop(recipient);
       
   498 		}
       
   499 
       
   500 	iFlags = aStream.ReadUint32L();
       
   501 	iBioMsgIdType = (TBioMsgIdType) aStream.ReadInt8L();
       
   502 	iMessage->InternalizeWithoutBufferL(aStream);
       
   503 #else
       
   504 	iMessage->InternalizeWithoutBufferL(aStream);
       
   505 #endif
       
   506 	}
       
   507 
       
   508 /**
       
   509 Externalises the object to the specified stream.
       
   510 
       
   511 @param	aStream
       
   512 The stream to be writen to.
       
   513 */
       
   514 EXPORT_C void CSmsHeader::ExternalizeL(RMsvWriteStream& aStream) const
       
   515 	{
       
   516 #if (!defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   517 
       
   518 	aStream.WriteInt16L(KMsvSmsHeaderVersion);
       
   519 
       
   520 	TInt count=iRecipients.Count();
       
   521 	aStream.WriteInt32L(count);
       
   522 
       
   523 	for (TInt i=0; i<count; i++)
       
   524 		iRecipients[i]->ExternalizeL(aStream);
       
   525 
       
   526 	aStream.WriteUint32L(iFlags);
       
   527 	aStream.WriteInt8L(iBioMsgIdType);
       
   528 	iMessage->ExternalizeWithoutBufferL(aStream); 
       
   529 #else
       
   530 	iMessage->ExternalizeWithoutBufferL(aStream); 	
       
   531 #endif 	
       
   532 	}
       
   533 
       
   534 /**
       
   535 Restores the object from the message entry store.
       
   536 
       
   537 The SMS object is restored from the KUidMsvSMSHeaderStream in the supplied store.
       
   538  
       
   539 @param	aStore
       
   540 The store from which the object is restored.
       
   541  
       
   542 @leave	KErrNotFound
       
   543 The stream KUidMsvSMSHeaderStream does not exist in aStore.
       
   544 */
       
   545 EXPORT_C void CSmsHeader::RestoreL(CMsvStore& aStore)
       
   546 	{
       
   547 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   548 	ReStoreDBL(aStore);
       
   549 	RMsvReadStream in;
       
   550 	in.OpenLC(aStore,KUidMsvSMSHeaderStream);
       
   551 	InternalizeL(in);
       
   552 	CleanupStack::PopAndDestroy(&in);
       
   553 #else
       
   554 
       
   555 	RMsvReadStream in;
       
   556 	in.OpenLC(aStore,KUidMsvSMSHeaderStream);
       
   557 	InternalizeL(in);
       
   558 	CleanupStack::PopAndDestroy(&in);
       
   559 	
       
   560 	iEmailFields->RestoreL(aStore);
       
   561 	
       
   562 #endif 
       
   563 	}
       
   564 
       
   565 
       
   566 /**
       
   567 Stores the object in the message entry store.
       
   568 
       
   569 The object is written to the KUidMsvSMSHeaderStream stream. Any previous content
       
   570 is overwritten.
       
   571 
       
   572 @param	aStore
       
   573 The store to hold the stream into which the object is written.
       
   574 */
       
   575 EXPORT_C void CSmsHeader::StoreL(CMsvStore& aStore) const
       
   576 	{
       
   577 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   578 	StoreDbL(aStore);
       
   579 	RMsvWriteStream out;
       
   580 	out.AssignLC(aStore,KUidMsvSMSHeaderStream);
       
   581 	ExternalizeL(out);
       
   582 	out.CommitL();
       
   583 	CleanupStack::PopAndDestroy(&out);
       
   584 
       
   585 #else
       
   586 	RMsvWriteStream out;
       
   587 	out.AssignLC(aStore,KUidMsvSMSHeaderStream);
       
   588 	ExternalizeL(out);
       
   589 	out.CommitL();
       
   590 	CleanupStack::PopAndDestroy(&out);
       
   591 	
       
   592 	iEmailFields->StoreL(aStore);
       
   593 #endif
       
   594 	}
       
   595 
       
   596 
       
   597 /**
       
   598 Check  whether a CMsvStore contains an SMS header stream.
       
   599 
       
   600 @param aStore The store.
       
   601 @return ETrue if there is a   SMS header
       
   602 */
       
   603 EXPORT_C TBool CSmsHeader::ContainsSmsHeaderL(const CMsvStore& aStore)
       
   604     {
       
   605     return aStore.IsPresentL(KUidMsvSMSHeaderStream);
       
   606     }
       
   607 
       
   608 CSmsHeader::CSmsHeader(CSmsMessage* aSmsMessage)
       
   609 :	iRecipients(KSmcmRecipientsGranularity),
       
   610 	iMessage(aSmsMessage),
       
   611 	iFlags(ESmsHeaderNoFlags),
       
   612 	iBioMsgIdType(EBioMsgIdNbs),
       
   613 	iCloseFs(ETrue)
       
   614 	{
       
   615 	}
       
   616 
       
   617 void CSmsHeader::ConstructL(CSmsPDU::TSmsPDUType aType, CEditableText& aText)
       
   618 	{
       
   619 	User::LeaveIfError(iFs.Connect());
       
   620 	iMessage=CSmsMessage::NewL(iFs, aType, CSmsEditorBuffer::NewL(aText), EFalse);
       
   621 	iEmailFields = CSmsEmailFields::NewL();
       
   622 	}
       
   623 	
       
   624 void CSmsHeader::ConstructL(CSmsPDU::TSmsPDUType aType, CEditableText& aText, RFs& aFs)
       
   625 	{
       
   626 	iFs=aFs;
       
   627 	iCloseFs = EFalse;
       
   628 	iMessage=CSmsMessage::NewL(iFs, aType, CSmsEditorBuffer::NewL(aText), EFalse);
       
   629 	iEmailFields = CSmsEmailFields::NewL();
       
   630 	}
       
   631 
       
   632 void CSmsHeader::ConstructL()
       
   633 	{
       
   634 	iEmailFields = CSmsEmailFields::NewL();
       
   635 
       
   636 	// Check the PID of the SMS PDU to see if set for interworking with email.
       
   637 	CSmsPDU& pdu = Message().SmsPDU();
       
   638 	if( pdu.ProtocolIdentifierPresent() &&
       
   639 		pdu.PIDType() == TSmsProtocolIdentifier::ESmsPIDTelematicInterworking &&
       
   640 		pdu.TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsTelematicDevice &&
       
   641 		pdu.TelematicDeviceType() == TSmsProtocolIdentifier::ESmsInternetElectronicMail )
       
   642 		{
       
   643 		__ASSERT_DEBUG( pdu.Type() == CSmsPDU::ESmsDeliver, User::Invariant() );
       
   644 		
       
   645 		// Ok, this is an email SMS - parse out the address and the optional 
       
   646 		// subject fields.
       
   647 		CSmsBufferBase& message = Message().Buffer();
       
   648 		TInt length = message.Length();
       
   649 		HBufC* buf = HBufC::NewLC(length);
       
   650 		TPtr bufPtr(buf->Des());
       
   651 		message.Extract(bufPtr, 0, length);
       
   652 		
       
   653 		TInt end = iEmailFields->ParseL(*buf);
       
   654 		
       
   655 		if( end > 0 )
       
   656 			{
       
   657 			TPtrC body((*buf).Mid(end));
       
   658 			message.Reset();
       
   659 			message.InsertL(0, body);
       
   660 			}
       
   661 		CleanupStack::PopAndDestroy(buf);
       
   662 		}
       
   663 	}
       
   664 
       
   665 void CSmsHeader::SetCanConcatenate(TBool aCanConcatenate)
       
   666 	{
       
   667 	iFlags = (iFlags & ~ESmsHeaderCanConcatenate) | (aCanConcatenate ? ESmsHeaderCanConcatenate : ESmsHeaderNoFlags);
       
   668 	}
       
   669 
       
   670 TBool CSmsHeader::CanConcatenate() const
       
   671 	{
       
   672 	return iFlags & ESmsHeaderCanConcatenate;
       
   673 	}
       
   674 
       
   675 /**
       
   676 Gets the summary information for the specified acknowledgement.
       
   677 
       
   678 If the specified acknowledgement is not recognised, then this function returns
       
   679 the default value of TMsvSmsEntryAckSummary::ENoAckSummary.
       
   680 nothing.
       
   681 
       
   682 @param
       
   683 aAckType	The requested acknowledgement summary.
       
   684 
       
   685 @return
       
   686 The acknowledgement summary information.
       
   687 
       
   688 @see
       
   689 TMsvSmsEntry::TMsvSmsEntryAckSummary
       
   690 */
       
   691 EXPORT_C TMsvSmsEntry::TMsvSmsEntryAckSummary TMsvSmsEntry::AckSummary(TSmsAckType aAckType) const
       
   692 	{
       
   693 	TMsvSmsEntryAckSummary summary = ENoAckSummary;
       
   694 	switch( aAckType )
       
   695 		{
       
   696 	case ESmsAckTypeDelivery:
       
   697 		summary = static_cast<TMsvSmsEntryAckSummary>((iMtmData2 & EMsvSmsEntryDeliveryAckSummary) >> EMsvSmsEntryDeliveryAckSummaryShift);
       
   698 		break;
       
   699 	default:
       
   700 		// Use default summary - fail gracefully.
       
   701 		break;
       
   702 		}
       
   703 	return summary;
       
   704 	}
       
   705 
       
   706 /**
       
   707 Sets the summary information for the specified acknowlwdgement.
       
   708 
       
   709 If the specified acknowledgement is not recognised, then this function does
       
   710 nothing.
       
   711 
       
   712 @param
       
   713 aAckType	The acknowledgement summary to be set.
       
   714 
       
   715 @param
       
   716 aAckSummary	The summary information.
       
   717 
       
   718 @see
       
   719 TMsvSmsEntry::TMsvSmsEntryAckSummary
       
   720 */
       
   721 EXPORT_C void TMsvSmsEntry::SetAckSummary(TSmsAckType aAckType, TMsvSmsEntryAckSummary aAckSummary)
       
   722 	{
       
   723 	switch( aAckType )
       
   724 		{
       
   725 	case ESmsAckTypeDelivery:
       
   726 		iMtmData2 = (iMtmData2 & ~EMsvSmsEntryDeliveryAckSummary) | ((aAckSummary << EMsvSmsEntryDeliveryAckSummaryShift) & EMsvSmsEntryDeliveryAckSummary);
       
   727 		break;
       
   728 	default:
       
   729 		// Do nothing - fail gracefully.
       
   730 		break;
       
   731 		}
       
   732 	}
       
   733 
       
   734 /**
       
   735 Gets the message log ID and a flag indicating if it is valid.
       
   736 
       
   737 The returned flag indicates whether the message log ID is valid. If it is valid
       
   738 then the message has only a single recipient that is pending a status report. In
       
   739 this case the returned message log ID refers to the recipient that is pending.
       
   740 
       
   741 If it is not valid then the message has more than one recipient that is pending 
       
   742 a status report. The message log ID should is not valid and should not be used.
       
   743 
       
   744 @param
       
   745 aMessageId	An output argument for the message log ID.
       
   746 
       
   747 @return
       
   748 A flag indicating whether the message log ID aMessageId is valid or not.
       
   749 */
       
   750 EXPORT_C TBool TMsvSmsEntry::MessageId(TInt32& aMessageId) const
       
   751 	{
       
   752 	aMessageId = iMtmData3;
       
   753 	return iMtmData2 & EMsvSmsMessageValid;
       
   754 	}
       
   755 
       
   756 /**
       
   757 Sets the message log ID and a flag indicating if it is valid.
       
   758 
       
   759 If the message has only a single recipient that is pending a status report then
       
   760 the message log ID for that recipient can be set in the index. The flag must be
       
   761 set to true.
       
   762 
       
   763 If the message has more than one recipient that is pending a status report then
       
   764 the message log ID must not be used. The flag must be set to false.
       
   765 
       
   766 This functionality cannot be used with bio-messages. This function will panic if
       
   767 used with a bio-message.
       
   768 
       
   769 @param
       
   770 aMessageId	The message log ID. Should only be used if aIsValid is true. It has
       
   771 			a default value of zero.
       
   772 
       
   773 @param
       
   774 aIsValid	A flag indicating if the message log ID is valid. This should have
       
   775 			a value or true if the message has only a single recipient pending
       
   776 			a status report.
       
   777 			
       
   778 @panic	USER	0
       
   779 This message is a bio-message and therefore the message ID field cannot be used.
       
   780 */
       
   781 EXPORT_C void TMsvSmsEntry::SetMessageId(TInt32 aMessageId, TBool aIsValid)
       
   782 	{
       
   783 	__ASSERT_ALWAYS( iBioType == 0, User::Invariant() );
       
   784 
       
   785 	aIsValid ? (iMtmData2 |= EMsvSmsMessageValid) : (iMtmData2 &= ~EMsvSmsMessageValid);
       
   786 	iMtmData3 = aMessageId;
       
   787 	}
       
   788 
       
   789 /** 
       
   790 Gets the reply to address if it exists, otherwise calls FromAddress().
       
   791 
       
   792 Only valid for SMS-DELIVER type messages. 
       
   793 @return
       
   794 The reply to address if it exists, otherwise the originator address as returned by FromAddress().
       
   795 */	
       
   796 TPtrC CSmsHeader::ReplyAddressL() const
       
   797 	{
       
   798 	
       
   799 	if(Type()==CSmsPDU::ESmsDeliver)
       
   800 		{
       
   801 		//Check for a reply address field
       
   802 		CSmsReplyAddressOperations& operations = STATIC_CAST(CSmsReplyAddressOperations&,Message().GetOperationsForIEL(CSmsInformationElement::ESmsReplyAddressFormat));
       
   803 		if(!operations.ContainsReplyAddressIEL())
       
   804 			{
       
   805 			//if there is no reply to field call FromAddress()
       
   806 			return FromAddress();	
       
   807 			}	
       
   808 		//return the reply to address
       
   809 		HBufC* replyAddressHBuf=operations.GetReplyAddressL();
       
   810 		return replyAddressHBuf->Des();			
       
   811 		}	
       
   812 	else
       
   813 		{
       
   814 		return FromAddress();		
       
   815 		}
       
   816 	}
       
   817 
       
   818 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   819 
       
   820 /**
       
   821 Stores the object in the message entry store in SQL DB.
       
   822 
       
   823 The object is written to the KUidMsvSMSHeaderStream stream. Any previous content
       
   824 is overwritten.
       
   825 
       
   826 @param	aStore
       
   827 The store to hold the stream into which the object is written.
       
   828 */
       
   829 
       
   830 void CSmsHeader::StoreDbL(CMsvStore& aStore) const
       
   831 	{
       
   832 	_LIT(KDetails,"");
       
   833 	
       
   834 	CHeaderFields* smsHeaderFields = new(ELeave) CHeaderFields();
       
   835 	CleanupStack::PushL(smsHeaderFields);
       
   836 	smsHeaderFields->iUid = KUidMsvSMSHeaderStream;
       
   837 	
       
   838 	// 1. Header version field.
       
   839 	CFieldPair* smsHeaderVersionfield = new(ELeave) CFieldPair();
       
   840 	CleanupStack::PushL(smsHeaderVersionfield);
       
   841 	smsHeaderVersionfield->iFieldNumValue = KMsvSmsHeaderVersion;
       
   842 	smsHeaderFields->iFieldPairList.AppendL(smsHeaderVersionfield);
       
   843 	CleanupStack::Pop(smsHeaderVersionfield);
       
   844 	
       
   845 	// 2. Recipient count field.
       
   846 	CFieldPair* smsRecipientCountField = new(ELeave) CFieldPair();
       
   847 	CleanupStack::PushL(smsRecipientCountField);
       
   848 	smsRecipientCountField->iFieldNumValue = iRecipients.Count();
       
   849 	smsHeaderFields->iFieldPairList.AppendL(smsRecipientCountField);
       
   850 	CleanupStack::Pop(smsRecipientCountField);
       
   851 	
       
   852 	// 3. Recipients field.
       
   853 	TInt size = 0;	
       
   854 	for (TInt i=0; i < iRecipients.Count(); i++)
       
   855 		{
       
   856 		size += sizeof(CMsvRecipient::TRecipientStatus);
       
   857 		size += 16;		// CMsvRecipient::iError (4), iRetries(4) and iTime (8)
       
   858 		size += Align4(iRecipients[i]->Address().Size());	// CSmsNumber::iNumber
       
   859 		size += Align4(iRecipients[i]->Name().Size());		// CSmsNumber::iName
       
   860 		size += sizeof(TLogId);								// CSmsNumber::iLogId
       
   861 		size += sizeof(CSmsNumber::TSmsAckStatus);			// CSmsNumber::iDeliveryStatus
       
   862 		size += 10;											// For delimiters
       
   863 		}
       
   864 
       
   865 	RBuf recipients;
       
   866 	CleanupClosePushL(recipients);
       
   867 	recipients.CreateL(size);
       
   868 
       
   869 	for (TInt i=0; i<iRecipients.Count(); i++)
       
   870 		{		
       
   871 		recipients.AppendNum(iRecipients[i]->Status()); //0
       
   872 		recipients.Append(KComma);
       
   873 		recipients.AppendNum(iRecipients[i]->Error()); //1
       
   874 		recipients.Append(KComma);
       
   875 		recipients.AppendNum(iRecipients[i]->Retries()); //2
       
   876 		recipients.Append(KComma);
       
   877 		recipients.AppendNum(iRecipients[i]->Time().Int64()); //3
       
   878 		recipients.Append(KComma);
       
   879 	
       
   880 		recipients.Append(iRecipients[i]->Address()); //4
       
   881 		recipients.Append(KComma);
       
   882 		recipients.Append(iRecipients[i]->Name()); //5
       
   883 		recipients.Append(KComma);
       
   884 		recipients.AppendNum(iRecipients[i]->LogId()); //6
       
   885 		recipients.Append(KComma);
       
   886 		recipients.AppendNum(iRecipients[i]->AckStatus(ESmsAckTypeDelivery)); //7
       
   887 		recipients.Append(KDelimiter);
       
   888 		}
       
   889 		
       
   890 	CFieldPair* smsRecipientsField = new(ELeave) CFieldPair();
       
   891 	CleanupStack::PushL(smsRecipientsField);
       
   892 	smsRecipientsField->iFieldTextValue = recipients.AllocL();
       
   893 	smsHeaderFields->iFieldPairList.AppendL(smsRecipientsField);
       
   894 				
       
   895 	CleanupStack::Pop(smsRecipientsField);	// smsRecipientsField
       
   896 	CleanupStack::PopAndDestroy();			// recipients
       
   897 
       
   898 	// 4. SMS Flag
       
   899 	CFieldPair* smsSmsFlags = new(ELeave) CFieldPair();
       
   900 	CleanupStack::PushL(smsSmsFlags);
       
   901 	smsSmsFlags->iFieldNumValue = iFlags;
       
   902 	smsHeaderFields->iFieldPairList.AppendL(smsSmsFlags);
       
   903 	CleanupStack::Pop(smsSmsFlags);
       
   904 	
       
   905 	// 5. BIO Msg Id
       
   906 	CFieldPair* smsBioMsgIdType = new(ELeave) CFieldPair();
       
   907 	CleanupStack::PushL(smsBioMsgIdType);
       
   908 	smsBioMsgIdType->iFieldNumValue = iBioMsgIdType;
       
   909 	smsHeaderFields->iFieldPairList.AppendL(smsBioMsgIdType);
       
   910 	CleanupStack::Pop(smsBioMsgIdType);
       
   911 	
       
   912 			
       
   913 	CFieldPair* smsdetailField = new (ELeave)CFieldPair();
       
   914 	CleanupStack::PushL(smsdetailField);
       
   915 	smsdetailField->iFieldName =  KDetails().AllocL();
       
   916 	smsdetailField->iFieldType = ETextField;
       
   917 	smsdetailField->iFieldTextValue = KNullDesC().AllocL();
       
   918 	smsHeaderFields->iFieldPairList.AppendL(smsdetailField);
       
   919 	CleanupStack::Pop(smsdetailField);
       
   920 
       
   921 	TMsvWriteStore storeWriter(aStore);
       
   922 	storeWriter.AssignL(smsHeaderFields);
       
   923 	storeWriter.CommitL();
       
   924 	
       
   925 	CleanupStack::Pop(smsHeaderFields);
       
   926 	
       
   927 	// 6.  SMS-Email UID
       
   928 	// 7.  SMS-EMail HeaderVersion
       
   929 	// 8.  Subject
       
   930 	// 9.  AddressCount
       
   931 	// 10. Addresses
       
   932 
       
   933 	iEmailFields->StoreDBL(aStore);	
       
   934 	
       
   935 	}
       
   936 
       
   937 /**
       
   938 Restores the object from the message entry store in SQL DB.
       
   939 
       
   940 The SMS object is restored from the KUidMsvSMSHeaderStream in the supplied store.
       
   941  
       
   942 @param	aStore
       
   943 The store from which the object is restored.
       
   944  
       
   945 @leave	KErrNotFound
       
   946 The stream KUidMsvSMSHeaderStream does not exist in aStore.
       
   947 */	
       
   948 	
       
   949 void CSmsHeader::ReStoreDBL(CMsvStore& aStore)	
       
   950 	{
       
   951 	
       
   952 	CHeaderFields* rcvHeaderRow = NULL;
       
   953 	TMsvReadStore storeReader(aStore, KUidMsvSMSHeaderStream);
       
   954 	storeReader.LoadL(rcvHeaderRow);
       
   955 
       
   956 	
       
   957 	iRecipients.ResetAndDestroy();
       
   958 	
       
   959 	TInt i = 0;
       
   960 	CFieldPair* rcvHeader = rcvHeaderRow->iFieldPairList[i];
       
   961 
       
   962 	TInt16 headerversion = rcvHeaderRow->iFieldPairList[i++]->iFieldNumValue; // header version.
       
   963 	TInt count = rcvHeaderRow->iFieldPairList[i++]->iFieldNumValue;
       
   964 	
       
   965 	HBufC* 	receipientList = rcvHeaderRow->iFieldPairList[i++]->iFieldTextValue->Des().AllocL();
       
   966 	CleanupStack::PushL(receipientList);
       
   967 	
       
   968 	TPtrC receipientListPtr = receipientList->Des();
       
   969 	GetRecipientL(receipientListPtr);
       
   970 
       
   971 	iFlags  = rcvHeaderRow->iFieldPairList[i++]->iFieldNumValue;
       
   972 	iBioMsgIdType = (TBioMsgIdType)rcvHeaderRow->iFieldPairList[i++]->iFieldNumValue ;
       
   973 
       
   974 	CleanupStack::PopAndDestroy(receipientList);
       
   975 	
       
   976 	iEmailFields->ReStoreDBL(aStore);
       
   977 	
       
   978 	}
       
   979 
       
   980 /**
       
   981 Get the recipient strring and Create the recipient.
       
   982 
       
   983 @param : aRecipientStr A TPtrC16.
       
   984 @return None.
       
   985 */
       
   986 void CSmsHeader::GetRecipientL(TDesC16& aRecipientStrList)
       
   987 	{
       
   988 	TPtrC16 aRecipientStr = aRecipientStrList.Left(aRecipientStrList.Length());
       
   989 	
       
   990 	if(aRecipientStr.Length()>0)
       
   991 		{
       
   992 		RArray<TPtrC16> smsNumberData;
       
   993 		TInt startPos = 0;
       
   994 		TInt firstSemiColonPos = aRecipientStr.Locate(';');
       
   995 		TInt lastSemiColonPos = aRecipientStr.LocateReverse(';');
       
   996 				
       
   997 		do
       
   998 			{
       
   999 			CSmsNumber* recipientNumber=CSmsNumber::NewL();  
       
  1000 			TPtrC16 str1 = aRecipientStr.Left(firstSemiColonPos+1); // First recipient
       
  1001 			startPos = str1.Locate(',') ;
       
  1002 			
       
  1003 			while(startPos != KErrNotFound )
       
  1004 				{
       
  1005 				TPtrC16 str2 = str1.Left(startPos);
       
  1006 				smsNumberData.Append(str2);
       
  1007 				
       
  1008 				startPos++;
       
  1009 				str1.Set(str1.Mid(startPos, str1.Length()- startPos));
       
  1010 			
       
  1011 				startPos = str1.Locate(',');
       
  1012 				if(startPos == KErrNotFound)
       
  1013 					{
       
  1014 					TPtrC16 str3;
       
  1015 					str3.Set(str1.Mid(0,str1.Length()-1));
       
  1016 					smsNumberData.Append(str3);
       
  1017 					break;
       
  1018 					}
       
  1019 					
       
  1020 				}
       
  1021 		
       
  1022 			recipientNumber->SetStatus((CMsvRecipient::TRecipientStatus)ConvertToTInt(smsNumberData[0]));
       
  1023 			recipientNumber->SetError(ConvertToTInt(smsNumberData[1]));
       
  1024 			recipientNumber->SetRetries(ConvertToTInt(smsNumberData[2]));
       
  1025 			TInt64 time = ConvertToTInt(smsNumberData[3]);
       
  1026 			recipientNumber->SetTimeValue(time);
       
  1027 			
       
  1028 			//CSmsNumber	
       
  1029 			recipientNumber->SetAddressL(smsNumberData[4]);
       
  1030 			recipientNumber->SetNameL(smsNumberData[5]);
       
  1031 			
       
  1032 			TLex logId(smsNumberData[6]);
       
  1033 			TInt32 logIdNum;
       
  1034 			logId.Val(logIdNum);
       
  1035 			recipientNumber->SetLogId(logIdNum);	
       
  1036 			
       
  1037 			TLex ackStatus(smsNumberData[7]);
       
  1038 			TInt32 ackStatusNum;
       
  1039 			recipientNumber->SetAckStatus( (TSmsAckType) ackStatus.Val(ackStatusNum), CSmsNumber::ENoAckRequested);
       
  1040 				
       
  1041 			iRecipients.AppendL(recipientNumber);
       
  1042 			smsNumberData.Reset();
       
  1043 			
       
  1044 			if(firstSemiColonPos != lastSemiColonPos)
       
  1045 				{
       
  1046 				aRecipientStr.Set(aRecipientStr.Mid(firstSemiColonPos+1,aRecipientStr.Length()-firstSemiColonPos-1));
       
  1047 				firstSemiColonPos = aRecipientStr.Locate(';');
       
  1048 				lastSemiColonPos = aRecipientStr.LocateReverse(';');
       
  1049 				}
       
  1050 			else	
       
  1051 				{
       
  1052 				break;	
       
  1053 				}
       
  1054 								
       
  1055 			}while(1);
       
  1056 		
       
  1057 		smsNumberData.Close();				
       
  1058 		}		
       
  1059 	}
       
  1060 
       
  1061 
       
  1062 /**
       
  1063  * Convert a String to an Integer.
       
  1064  * @param aStr A string to make Integer.
       
  1065  * @return TInt A integer value 
       
  1066  */
       
  1067  TInt CSmsHeader::ConvertToTInt(TDesC16& aStr)
       
  1068 	{
       
  1069 	TLex str(aStr);
       
  1070 	TInt32 string;
       
  1071 	str.Val(string);
       
  1072 	return string;
       
  1073 	}
       
  1074 
       
  1075 #endif