smsprotocols/smsstack/smsprot/Src/smspfacadestor.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2007-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 "gsmubuf.h"
       
    17 #include "smspfacadestor.h"
       
    18 
       
    19 /**
       
    20 Static factory constructor. Uses two phase 
       
    21 construction and leaves nothing on the CleanupStack.
       
    22 
       
    23 @internalComponent
       
    24 
       
    25 @return A pointer to the newly created CFacadeSmsReassemblyStore object.
       
    26 @param aFs  File Server handle.
       
    27 @param aSmsComm  Notification Event Reference.
       
    28 @leave KErrNoMemory
       
    29 
       
    30 @pre A connected file server session must be passed as parameter.
       
    31 @post CFacadeSmsReassemblyStore object is now fully initialised
       
    32 */
       
    33 CFacadeSmsReassemblyStore* CFacadeSmsReassemblyStore::NewL(RFs& aFs, MSmsComm& aSmsComm)
       
    34 	{
       
    35 	LOGSMSPROT1("CFacadeSmsReassemblyStore::NewL()");
       
    36 
       
    37 	CFacadeSmsReassemblyStore*  self = new (ELeave) CFacadeSmsReassemblyStore(aFs, aSmsComm);
       
    38 	CleanupStack::PushL(self);
       
    39 	self->ConstructL();
       
    40 	CleanupStack::Pop(self);
       
    41 
       
    42 	return self;
       
    43 	}
       
    44 
       
    45 /**
       
    46  *  Constructor.
       
    47 */
       
    48 CFacadeSmsReassemblyStore::CFacadeSmsReassemblyStore(RFs& aFs, MSmsComm& aSmsComm)
       
    49 	:iFs(aFs), iSmsComm(aSmsComm), iReassemblyStore(NULL), iClass0ReassemblyStore(NULL)
       
    50 	{
       
    51 	// NOP
       
    52 	}
       
    53 
       
    54 /**
       
    55  *  Destructor. It destroys all the member variables.
       
    56 */
       
    57 CFacadeSmsReassemblyStore::~CFacadeSmsReassemblyStore()
       
    58 	{
       
    59 	LOGSMSPROT1("~CFacadeSmsReassemblyStore()");
       
    60 	iReassemblyStore->Close();
       
    61 	delete iReassemblyStore;
       
    62 
       
    63 	if (iClass0ReassemblyStore)
       
    64 		{
       
    65 		iClass0ReassemblyStore->Close();
       
    66 		delete iClass0ReassemblyStore;
       
    67 		}
       
    68 	}
       
    69 
       
    70 /**
       
    71 Second Phase construction. It creates re-assembly stores. If SMS stack is configured
       
    72 for handling class 0 messages in out-of-disk condition. It creates class 0 
       
    73 & non-class 0 re-assembly store. Otherwise it creates only one re-assembly store
       
    74 which will be used to store all type of SMS messages.
       
    75 
       
    76 @internalComponent
       
    77 
       
    78 @leave KErrNoMemory
       
    79 
       
    80 @pre A connected file server session must be passed as parameter.
       
    81 @post CFacadeSmsReassemblyStore object is now fully constructed.
       
    82 */
       
    83 void CFacadeSmsReassemblyStore::ConstructL()
       
    84 	{
       
    85 	LOGSMSPROT1("CFacadeSmsReassemblyStore::ConstructL()");
       
    86 
       
    87 	iReassemblyStore = CSmsReassemblyStore::NewL(iFs);
       
    88 	/*
       
    89 	Read [ReassemblyStore] section from smswap.sms.esk file. If section is absent then there is
       
    90 	no need to create class 0 re-assembly store. This sms stack is configured to work
       
    91 	as before (class 0 message will be -vely ack in out-of-disk condition).
       
    92 	If ReassemblyStore section is present then read the value of Class0.
       
    93 	If the value of Class0 is 1. Then create class 0 re-assembly store object.
       
    94 	For example:
       
    95 	[ReassemblyStore]
       
    96 	Class0= 1
       
    97 	MaxClass0Messages=10
       
    98 	NumberOfPDUSegements=20
       
    99 	GuardTimeOut=12
       
   100 	*/
       
   101 	CESockIniData*  ini = NULL;
       
   102 	ini=CESockIniData::NewL(_L("smswap.sms.esk"));
       
   103 	CleanupStack::PushL(ini);
       
   104 	TBool status(EFalse);
       
   105 	if (ini->FindVar(_L("ReassemblyStore"), _L("Class0"), status))
       
   106 		{
       
   107 		if (status)
       
   108 			{
       
   109 			iClass0ReassemblyStore = CClass0SmsReassemblyStore::NewL(iFs, iSmsComm);
       
   110 			}
       
   111 		}
       
   112 
       
   113 	// Set the default value for iMaxmumNumberOfCompleteMessagesInReassemblyStore.
       
   114 	iMaxmumNumberOfCompleteMessagesInReassemblyStore = KDefaultMaxmumNumberOfCompleteMessagesInReassemblyStore;
       
   115 	// Load up the user configurable setting for the maximum number of complete messages in 
       
   116 	// the reassembly store.
       
   117 	TPtrC value;
       
   118 	if((ini->FindVar(_L("ReasmemblyStoreOptions"),_L("MaxNumOfComMessInReStore"),value)))
       
   119 		{
       
   120 		TLex16 valueconv(value);
       
   121 		valueconv.Val(iMaxmumNumberOfCompleteMessagesInReassemblyStore); 
       
   122 		}
       
   123 
       
   124 	CleanupStack::PopAndDestroy(ini);
       
   125 	}
       
   126 
       
   127 /**
       
   128 It open the re-assembly stores.
       
   129 This function needs to be called before doing any operations (add/delete/update) in the 
       
   130 re-assembly stores.
       
   131 
       
   132 @internalComponent
       
   133 */
       
   134 void CFacadeSmsReassemblyStore::OpenStoreL()
       
   135 	{
       
   136 	LOGSMSPROT1("CFacadeSmsReassemblyStore::OpenStoreL()");
       
   137 	iReassemblyStore->OpenStoreL();
       
   138 	if (iClass0ReassemblyStore)
       
   139 		{
       
   140 		iClass0ReassemblyStore->OpenStoreL();
       
   141 		}
       
   142 	}
       
   143 
       
   144 /**
       
   145 It closes the re-assembly stores.
       
   146 
       
   147 @internalComponent
       
   148 */
       
   149 void CFacadeSmsReassemblyStore::Close()
       
   150 	{
       
   151 	LOGSMSPROT1("CFacadeSmsReassemblyStore::Close()");
       
   152 	// Close general Re-assembly store.
       
   153 	iReassemblyStore->Close();
       
   154 	// Close Class0 re-assembly store.
       
   155 	if (iClass0ReassemblyStore)
       
   156 		{
       
   157 		iClass0ReassemblyStore->Close();
       
   158 		}
       
   159 	}
       
   160 
       
   161 /**
       
   162 It returns the file session.
       
   163 
       
   164 @internalComponent
       
   165 
       
   166 @return returns the file session.
       
   167 */
       
   168 RFs& CFacadeSmsReassemblyStore::FileSession() const
       
   169 	{
       
   170 	return iFs;
       
   171 	}
       
   172 
       
   173 /**
       
   174 It initializes the re-assembly store.
       
   175 It goes through all the entries in re-assembly store. It updates its header information.
       
   176 If any sms message is either SIM based or combined storage based then it is deleted from re-assembly store.
       
   177 For other type of SMS messages, its header info is updated to indicate that it is not passed to client.
       
   178 
       
   179 This initialization process is required because SMS stack might have been re-started.
       
   180 
       
   181 @internalComponent
       
   182 */
       
   183 void CFacadeSmsReassemblyStore::InitL()
       
   184 	{
       
   185 	LOGSMSPROT1("CFacadeSmsReassemblyStore::InitL()");
       
   186 	// Initialize Non-class 0 Re-assembly store.
       
   187 	InitializeNonClass0StoreL();
       
   188 	// Initialize Class0 re-assembly store.
       
   189 	if (iClass0ReassemblyStore)
       
   190 		{
       
   191 		iClass0ReassemblyStore->InitializeL();
       
   192 		}
       
   193 	}
       
   194 
       
   195 /**
       
   196 Purges the reassembly file stores.
       
   197 
       
   198 @param aTimeIntervalMinutes Purge time
       
   199 @param aPurgeIncompleteOnly Purge complete messages flag
       
   200 
       
   201 @internalComponent
       
   202 */
       
   203 void CFacadeSmsReassemblyStore::PurgeL(const TTimeIntervalMinutes& aTimeIntervalMinutes,TBool aPurgeIncompleteOnly)
       
   204 	{
       
   205 	LOGSMSPROT1("CFacadeSmsReassemblyStore::PurgeL()");
       
   206 	iReassemblyStore->PurgeL(aTimeIntervalMinutes, aPurgeIncompleteOnly);
       
   207 	if (iClass0ReassemblyStore)
       
   208 		{
       
   209 		iClass0ReassemblyStore->PurgeL(aTimeIntervalMinutes, aPurgeIncompleteOnly);
       
   210 		}
       
   211 	}
       
   212 
       
   213 /**
       
   214 It returns a boolean value indicating whether re-assembly store is full or not.
       
   215 If number of complete sms messages exceed the configured value (KMaxmumNumberOfCompleteMessagesInReassemblyStore),
       
   216 it return TRUE. Otherwise it returns FALSE.
       
   217 
       
   218 @internalComponent
       
   219 */
       
   220 TBool CFacadeSmsReassemblyStore::IsFull()
       
   221 	{
       
   222 	LOGSMSPROT1("CFacadeSmsReassemblyStore::IsFull()");
       
   223 
       
   224 	//local variable for complete entries
       
   225 	TInt count( 0 );
       
   226 	count = NumberOfCompleteNonClass0Messages();
       
   227 	if (iClass0ReassemblyStore)
       
   228 		{
       
   229 		count += iClass0ReassemblyStore->NumberOfCompleteMessages();
       
   230 		}
       
   231 	if (count > iMaxmumNumberOfCompleteMessagesInReassemblyStore)
       
   232 		{
       
   233 		return ETrue;
       
   234 		}
       
   235 	else
       
   236 		{
       
   237 		return EFalse;
       
   238 		}
       
   239 	}
       
   240 
       
   241 /**
       
   242 It deletes all the enumerated SIM messages stored in re-assembly store.
       
   243 This function will be called if user choses to cancel the enumeration.
       
   244 
       
   245 @internalComponent
       
   246 */
       
   247 void CFacadeSmsReassemblyStore::DeleteEnumeratedSIMEntries()
       
   248 	{
       
   249 	LOGSMSPROT1("CFacadeSmsReassemblyStore::DeleteEnumeratedSIMEntries()");
       
   250 	DeleteNonClass0EnumeratedSIMEntries();
       
   251 	if (iClass0ReassemblyStore)
       
   252 		{
       
   253 		iClass0ReassemblyStore->DeleteEnumeratedSIMEntries();
       
   254 		}
       
   255 	}
       
   256 
       
   257 /**
       
   258 It externalizes all the enumerated messages.
       
   259 It goes through the re-assembly store and sends all those SMS messages 
       
   260 (which is SIM/Combined storage based) to client (aSmsProvider).
       
   261 
       
   262 @param aSmsProvider  a reference to a service access point.
       
   263 @param aCount	number of sms messages enumerated.
       
   264 @return number of new segments.
       
   265 
       
   266 @internalComponent
       
   267 */
       
   268 TInt CFacadeSmsReassemblyStore::ExternalizeEnumeratedMessagesL(CSmsProvider& aProvider,TInt& aCount)
       
   269 	{
       
   270 	LOGSMSPROT1("CFacadeSmsReassemblyStore::ExternalizeEnumeratedMessagesL()");
       
   271 	TInt numNewSegments(0);
       
   272 	numNewSegments = ExternalizeEnumeratedNonClass0SmsMessagesL(aProvider, aCount);
       
   273 	if (iClass0ReassemblyStore)
       
   274 		{
       
   275 		numNewSegments += ExternalizeEnumeratedClass0SmsMessagesL(aProvider, aCount);
       
   276 		}
       
   277 	return numNewSegments;
       
   278 	}
       
   279 
       
   280 /**
       
   281 It searches the reassembly store for complete messages and then it sends that 
       
   282 message for further processing. It is called when a new observer is added or 
       
   283 a PDU has been received and successfully processed.
       
   284 
       
   285 @param aSmsComm  a reference to the protocol.
       
   286 @param aCurrentSmsMessage	a pointer to current SMS message.
       
   287 
       
   288 @internalComponent
       
   289 */
       
   290 void CFacadeSmsReassemblyStore::ProcessCompleteSmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage* aCurrentSmsMessage)
       
   291 	{
       
   292 	LOGSMSPROT1("CFacadeSmsReassemblyStore::ProcessCompleteSmsMessagesL");
       
   293 
       
   294 	ProcessCompleteNonClass0SmsMessagesL(aSmsComm, aCurrentSmsMessage);
       
   295 	if (iClass0ReassemblyStore)
       
   296 		{
       
   297 		ProcessCompleteClass0SmsMessagesL(aSmsComm, aCurrentSmsMessage);
       
   298 		}
       
   299 	}
       
   300 
       
   301 /**
       
   302 It adds the message segment to the reassembly store.
       
   303 This function first checks on which re-assembly store the message should be stored and then add
       
   304 the message to appropriate re-assembly store.
       
   305 
       
   306 @note Only SUBMIT or DELIVER PDUs can be added to the reassembly store.
       
   307 
       
   308 @param aSmsMessage  a reference to the SMS message.
       
   309 	It acts both as input & output. At the time of function call it contains the message.
       
   310 	When the function returns it contains full decoded message if it is complete.
       
   311 	But in case of class 0 messages it might not contain complete class 0 messages.
       
   312 
       
   313 @param aGsmSms	a reference to GsmSms object which contain actual PDU.
       
   314 	It acts as pure input.
       
   315 
       
   316 @param aIsComplete  boolean value indicating whether the message is complete or not.
       
   317 	It acts both as input & output.
       
   318 	In case of multi-segment message, the value of aIsComplete will be true when function returns 
       
   319 	if the added segment makes the messsage complete.
       
   320 
       
   321 @param aIsEnumeration	boolean value indicating whether the function is called at the time of enumeration.
       
   322 	It acts as only input.
       
   323 
       
   324 @param aCount  value indicating the number of current PDUs in the re-assembly store for the given SMS message.
       
   325 	It acts as only output.
       
   326 
       
   327 @param aTotal	value indicating the total number of PDUs for the given sms message.
       
   328 	It acts as only output.
       
   329 
       
   330 @internalComponent
       
   331 
       
   332 NOTE:
       
   333 	When function returns, if the value of aIsComplete is True, then aSmsMesssage will contain the
       
   334 	complete decoded SMS message.
       
   335 	But the above statement might not be always true:
       
   336 	In case of class 0 messages, it is possible to forward the incomplete messages. So after forwarding
       
   337 	the incomplete message, if we receive other constituent PDU of that message then in that case we 
       
   338 	might receive all the constituent PDU of that message but aSmsMesssage will contain partial complete message.
       
   339 	To find out complete/incompletness of the message, CSmsMessage::IsComplete() message function has to be called.
       
   340 */
       
   341 void CFacadeSmsReassemblyStore::AddSegmentToReassemblyStoreL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms, TInt& aIndex, TBool& aIsComplete, TBool aIsEnumeration, TInt& aCount, TInt& aTotal)
       
   342 	{
       
   343 	LOGSMSPROT2("CFacadeSmsReassemblyStore::AddSegmentToReassemblyStoreL(): isComplete Message=%d",
       
   344 				aSmsMessage.IsComplete());
       
   345 
       
   346 	TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
       
   347 
       
   348 	if (toBeStoredInClass0ReassemblyStore)
       
   349 		{
       
   350 		iClass0ReassemblyStore->AddSegmentToReassemblyStoreL(aSmsMessage, aGsmSms, aIndex, aIsComplete, aIsEnumeration, aCount, aTotal);
       
   351 		}
       
   352 	else
       
   353 		{
       
   354 		AddSegmentToNonClass0ReassemblyStoreL(aSmsMessage, aGsmSms, aIndex, aIsComplete, aIsEnumeration, aCount, aTotal);
       
   355 		}
       
   356 	}
       
   357 
       
   358 /**
       
   359 It forwards the complete class 0 messages to client.
       
   360 NOTE:
       
   361 	This function needs to be called only in case of class 0 messages.
       
   362 
       
   363 @param aSmsComm  a reference to aSmsComm object which implemented the events.
       
   364 
       
   365 @param aSmsMessage	a reference to sms message object. This sms message must be class 0 messages.
       
   366 
       
   367 @param aOriginalSmsAddr pointer to the address of the sender of a previously sent
       
   368 
       
   369 @param aOriginalSmsMessage pointer to a message previously sent matched to the received 
       
   370 							one (e.g. status report).	Null if not matched.
       
   371 
       
   372 @param aDes user data for the deliver report acknowledging this message to the SC.
       
   373 			Filled in by the observer.
       
   374 
       
   375 @internalComponent
       
   376 */
       
   377 void CFacadeSmsReassemblyStore::ForwardCompleteClass0SmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage& aSmsMessage,const TSmsAddr* aOriginalSmsAddr,const CSmsMessage* aOriginalSmsMessage,TDes& aDes)
       
   378 	{
       
   379 	LOGSMSPROT1("CFacadeSmsReassemblyStore::ForwardCompleteClass0SmsMessagesL");
       
   380 	if (iClass0ReassemblyStore)
       
   381 		{
       
   382 		iClass0ReassemblyStore->ForwardCompleteClass0SmsMessagesL(aSmsComm, aSmsMessage, aOriginalSmsAddr, aOriginalSmsMessage, aDes);
       
   383 		}
       
   384 	}
       
   385 
       
   386 /**
       
   387 It frees the space by forwarding the class 0 message if class 0 re-assembly store 
       
   388 exceeds limitation (max class 0 message, max reserved pdu segment).
       
   389 NOTE:
       
   390 	This function needs to be called only in case of class 0 messages.
       
   391 
       
   392 @param aSmsComm  a reference to aSmsComm object which implemented the events.
       
   393 
       
   394 @internalComponent
       
   395 */
       
   396 void CFacadeSmsReassemblyStore::ProcessMessageIfExceedLimitationL(MSmsComm& aSmsComm)
       
   397 	{
       
   398 	LOGSMSPROT1("CFacadeSmsReassemblyStore::ProcessMessageIfExceedLimitationL");
       
   399 	if (iClass0ReassemblyStore)
       
   400 		{
       
   401 		iClass0ReassemblyStore->ProcessMessageIfExceedLimitationL(aSmsComm);
       
   402 		}
       
   403 	}
       
   404 
       
   405 /**
       
   406 It sets the incomplete messsage forwarded to client.
       
   407 Internally it frees up the memory by removing the forwarded PDUs and also it stores forwarded PDU index.
       
   408 
       
   409 NOTE:
       
   410 	This function needs to be called only in case of class 0 messages.
       
   411 
       
   412 @param aSmsMessage	a reference to sms message object. This sms message must be class 0 messages.
       
   413 
       
   414 @internalComponent
       
   415 */
       
   416 void CFacadeSmsReassemblyStore::SetIncompleteMessageForwardedToClientL(const CSmsMessage& aSmsMessage)
       
   417 	{
       
   418 	LOGSMSPROT1("CFacadeSmsReassemblyStore::SetIncompleteMessageForwardedToClientL()");
       
   419 	if (iClass0ReassemblyStore)
       
   420 		{
       
   421 		iClass0ReassemblyStore->SetIncompleteMessageForwardedToClientL(aSmsMessage);
       
   422 		}
       
   423 	}
       
   424 
       
   425 /**
       
   426 It sets the disk space status.
       
   427 If disk space is full, then class 0 re-assembly store stores the incoming message in
       
   428 pre-allocated file. Otherwise it stores the message in permanent store file.
       
   429 */
       
   430 void CFacadeSmsReassemblyStore::SetDiskSpaceState(TSmsDiskSpaceMonitorStatus aDiskSpaceStatus)
       
   431 	{
       
   432 	LOGSMSPROT1("CFacadeSmsReassemblyStore::SetDiskSpaceState()");
       
   433 	if (iClass0ReassemblyStore)
       
   434 		{
       
   435 		iClass0ReassemblyStore->SetDiskSpaceState(aDiskSpaceStatus);
       
   436 		}
       
   437 	}
       
   438 
       
   439 /**
       
   440 It deletes the given SMS message from re-assembly store.
       
   441 
       
   442 @param aSmsMessage  Message to delete.
       
   443 @param aPassed      Determines if we are searching for a message already
       
   444 					passed to the client.
       
   445 
       
   446 @internalComponent
       
   447 */
       
   448 void CFacadeSmsReassemblyStore::DeleteMessageL(const CSmsMessage& aSmsMessage, TBool aPassed)
       
   449 	{
       
   450 	LOGSMSPROT1("CFacadeSmsReassemblyStore::DeleteEntryL()");
       
   451 
       
   452 	TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
       
   453 
       
   454 	if (toBeStoredInClass0ReassemblyStore)
       
   455 		{
       
   456 		iClass0ReassemblyStore->DeleteMessageL(aSmsMessage, aPassed);
       
   457 		}
       
   458 	else
       
   459 		{
       
   460 		DeleteNonClass0MessageL(aSmsMessage, aPassed);
       
   461 		}
       
   462 	}
       
   463 
       
   464 /**
       
   465 It updates log server id of the passed message in re-assembly store.
       
   466 
       
   467 @param aSmsMessage  a reference to a message.
       
   468 @param aIndex	index number of sms message to be updated.
       
   469 
       
   470 @internalComponent
       
   471 */
       
   472 void CFacadeSmsReassemblyStore::UpdateLogServerIdL(const CSmsMessage& aSmsMessage, TInt aIndex)
       
   473 	{
       
   474 	LOGSMSPROT1("CFacadeSmsReassemblyStore::UpdateLogServerIdL()");
       
   475 
       
   476 	TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
       
   477 
       
   478 	if (toBeStoredInClass0ReassemblyStore)
       
   479 		{
       
   480 		iClass0ReassemblyStore->UpdateLogServerIdOfMessageL(aSmsMessage, aIndex);
       
   481 		}
       
   482 	else
       
   483 		{
       
   484 		UpdateLogServerIdOfNonClass0MessageL(aSmsMessage, aIndex);
       
   485 		}
       
   486 	}
       
   487 
       
   488 /**
       
   489 It updates that the given SMS message in re-assembly store is passed to client.
       
   490 
       
   491 @param aSmsMessage  Message which is passed to client.
       
   492 
       
   493 @internalComponent
       
   494 */
       
   495 void CFacadeSmsReassemblyStore::SetMessagePassedToClientL(const CSmsMessage& aSmsMessage, TBool aPassed)
       
   496 	{
       
   497 	LOGSMSPROT1("CFacadeSmsReassemblyStore::SetMessagePassedToClientL()");
       
   498 
       
   499 	TBool toBeStoredInClass0ReassemblyStore = IsForClass0ReassemblyStore(aSmsMessage);
       
   500 
       
   501 	if (toBeStoredInClass0ReassemblyStore)
       
   502 		{
       
   503 		iClass0ReassemblyStore->SetMessagePassedToClientL(aSmsMessage, aPassed);
       
   504 		}
       
   505 	else
       
   506 		{
       
   507 		SetNonClass0MessagePassedToClientL(aSmsMessage, aPassed);
       
   508 		}
       
   509 	}
       
   510 
       
   511 /**
       
   512 Returns a boolean value indicating whether this class contains separate
       
   513 re-assembly store for class 0 message or not.
       
   514 
       
   515 @internalComponent
       
   516 */
       
   517 TBool CFacadeSmsReassemblyStore::IsSeparateClass0StoreSupported()
       
   518 	{
       
   519 	if (iClass0ReassemblyStore)
       
   520 		{
       
   521 		return ETrue;
       
   522 		}
       
   523 	else
       
   524 		{
       
   525 		return EFalse;
       
   526 		}
       
   527 	}
       
   528 
       
   529 /**
       
   530 Returns a boolean value indicating where this SMS message will be stored.
       
   531 If it rerurns EFalse, message will be stored in normal re-assembly store,
       
   532 otherwise it will be stored in class 0 re-assembly store.
       
   533 
       
   534 @internalComponent
       
   535 */
       
   536 TBool CFacadeSmsReassemblyStore::IsForClass0ReassemblyStore(const CSmsMessage& aSmsMessage)
       
   537 	{
       
   538 	if (iClass0ReassemblyStore == NULL)
       
   539 		{
       
   540 		return EFalse;
       
   541 		}
       
   542 
       
   543 	TSmsDataCodingScheme::TSmsClass  msgClass;
       
   544 
       
   545 	if (aSmsMessage.SmsPDU().DataCodingSchemePresent()	&&	aSmsMessage.SmsPDU().Class(msgClass))
       
   546 		{
       
   547 		if (msgClass == TSmsDataCodingScheme::ESmsClass0)
       
   548 			{
       
   549 			//Check also whether it is a WAP Datagram
       
   550 			// In that case return EFalse otherwise ETrue (REQ7012)
       
   551 			if (!IsWapSMS(aSmsMessage))
       
   552 				{
       
   553 				return ETrue;
       
   554 				}
       
   555 			}
       
   556 		}
       
   557 	return EFalse;
       
   558 	}
       
   559 
       
   560 /**
       
   561 It initializes the re-assembly store.
       
   562 It goes through all the entries in re-assembly store. It updates its header information.
       
   563 If any sms message is either SIM based or combined storage based then it is deleted from re-assembly store.
       
   564 For other type of SMS messages, its header info is updated to indicate that it is not passed to client.
       
   565 
       
   566 This initialization process is required because SMS stack might have been re-started.
       
   567 
       
   568 @internalComponent
       
   569 */
       
   570 void CFacadeSmsReassemblyStore::InitializeNonClass0StoreL()
       
   571 	{
       
   572 	LOGSMSPROT1("CFacadeSmsReassemblyStore::InitializeNonClass0StoreL()");
       
   573 	// Initialize Re-assembly store.
       
   574 	iReassemblyStore->OpenStoreL();
       
   575 	iReassemblyStore->BeginTransactionLC();
       
   576 	TInt count = iReassemblyStore->Entries().Count();
       
   577 	while (count--)
       
   578 		{
       
   579 		TSmsReassemblyEntry entry= (TSmsReassemblyEntry&) iReassemblyStore->Entries()[count];
       
   580 		CSmsPDU::TSmsPDUType pdu = entry.PduType();
       
   581 		CSmsBuffer* buffer = CSmsBuffer::NewL();
       
   582 		CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, pdu, buffer );
       
   583 		CleanupStack::PushL(smsMessage);
       
   584 		iReassemblyStore->GetMessageL(count,*smsMessage);
       
   585 		if ((smsMessage->Storage() == CSmsMessage::ESmsSIMStorage) || (smsMessage->Storage() == CSmsMessage::ESmsCombinedStorage))
       
   586 			{
       
   587 			iReassemblyStore->DeleteEntryL(count);
       
   588 			}
       
   589 		else
       
   590 			{
       
   591 			iReassemblyStore->SetPassedToClientL(count, EFalse);
       
   592 			}
       
   593 		CleanupStack::PopAndDestroy(smsMessage);
       
   594 		}
       
   595 	iReassemblyStore->CommitTransactionL();
       
   596 	iReassemblyStore->Close();
       
   597 	}
       
   598 
       
   599 /**
       
   600 It deletes all the enumerated SIM messages stored in re-assembly store.
       
   601 This function will be called if user choses to cancel the enumeration.
       
   602 
       
   603 @internalComponent
       
   604 */
       
   605 void CFacadeSmsReassemblyStore::DeleteNonClass0EnumeratedSIMEntries()
       
   606 	{
       
   607 	const TInt count = iReassemblyStore->Entries().Count();
       
   608 
       
   609 	LOGSMSPROT2("CFacadeSmsReassemblyStore::DeleteNonClass0EnumeratedSIMEntries(): %d messages in RAS", count);
       
   610 
       
   611 	TInt index;
       
   612 
       
   613 	for (index = count-1;  index >= 0;  --index)
       
   614 		{
       
   615 		TSmsReassemblyEntry  entry = (TSmsReassemblyEntry&) iReassemblyStore->Entries()[index];
       
   616 
       
   617 		if (entry.Storage()==CSmsMessage::ESmsSIMStorage)
       
   618 			{
       
   619 			TRAP_IGNORE(iReassemblyStore->BeginTransactionLC();
       
   620 						iReassemblyStore->DeleteEntryL(index);
       
   621 						iReassemblyStore->CommitTransactionL());
       
   622 			}
       
   623 		}
       
   624 	}
       
   625 
       
   626 /**
       
   627 It deletes the given SMS message from re-assembly store.
       
   628 
       
   629 @param aSmsMessage  Message to delete.
       
   630 @param aPassed      Determines if we are searching for a message already
       
   631 					passed to the client.
       
   632 
       
   633 @internalComponent
       
   634 */
       
   635 void CFacadeSmsReassemblyStore::DeleteNonClass0MessageL(const CSmsMessage& aSmsMessage, TBool aPassed)
       
   636 	{
       
   637 	LOGSMSPROT1("CFacadeSmsReassemblyStore::DeleteNonClass0MessageL()");
       
   638 	TInt index(0);
       
   639 
       
   640 	if(!iReassemblyStore->InTransaction())
       
   641 		{
       
   642 		iReassemblyStore->BeginTransactionLC();
       
   643  		if (iReassemblyStore->FindMessageL(aSmsMessage, aPassed, index))
       
   644  			{
       
   645 			iReassemblyStore->DeleteEntryL(index);
       
   646  			}
       
   647 		iReassemblyStore->CommitTransactionL();
       
   648 		}
       
   649 	else if (iReassemblyStore->FindMessageL(aSmsMessage, aPassed,  index))
       
   650 		{
       
   651 		iReassemblyStore->DeleteEntryL(index);
       
   652 		}
       
   653 	}
       
   654 
       
   655 /**
       
   656 It updates that the given SMS message in re-assembly store is passed to client.
       
   657 
       
   658 @param aSmsMessage  Message which is passed to client.
       
   659 
       
   660 @internalComponent
       
   661 */
       
   662 void CFacadeSmsReassemblyStore::SetNonClass0MessagePassedToClientL(const CSmsMessage& aSmsMessage, TBool aPassed)
       
   663 	{
       
   664 	LOGSMSPROT1("CFacadeSmsReassemblyStore::SetNonClass0MessagePassedToClientL()");
       
   665 	TInt index(0);
       
   666 
       
   667 	iReassemblyStore->BeginTransactionLC();
       
   668 	if (iReassemblyStore->FindMessageL(aSmsMessage , !aPassed, index))
       
   669 		{
       
   670  		iReassemblyStore->SetPassedToClientL(index, aPassed);
       
   671  		}
       
   672 	iReassemblyStore->CommitTransactionL();
       
   673 	}
       
   674 
       
   675 /**
       
   676 It returns the number of complete messages stored in general re-assembly store.
       
   677 */
       
   678 TInt CFacadeSmsReassemblyStore::NumberOfCompleteNonClass0Messages()
       
   679 	{
       
   680 	LOGSMSPROT2("CFacadeSmsReassemblyStore::NumberOfCompleteMessages(): Entries().Count()=%d",
       
   681 				iReassemblyStore->Entries().Count());
       
   682 
       
   683 	//local variable for complete entries
       
   684 	TInt count( 0 );
       
   685 	// checks all entrys in the reassembly store
       
   686 	for ( TInt i = iReassemblyStore->Entries().Count()-1; i >= 0; i-- )
       
   687 		{
       
   688 		// checks if entry is completed
       
   689 		if ( iReassemblyStore->Entries()[i].IsComplete() )
       
   690 			{
       
   691 			++count;
       
   692 			}
       
   693 		}
       
   694 	return count;
       
   695 	}
       
   696 
       
   697 /**
       
   698 It searches the non class 0 reassembly store for complete messages and then 
       
   699 it sends that message for further processing. It is called when a new 
       
   700 observer is added or a PDU has been received and successfully processed.
       
   701 
       
   702 @param aSmsComm  a reference to the protocol.
       
   703 @param aCurrentSmsMessage	a pointer to current SMS message.
       
   704 
       
   705 @internalComponent
       
   706 */
       
   707 void CFacadeSmsReassemblyStore::ProcessCompleteNonClass0SmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage* aCurrentSmsMessage)
       
   708 	{
       
   709 	LOGSMSPROT2("CFacadeSmsReassemblyStore::ProcessCompleteNonClass0SmsMessagesL [from %d to 0]", iReassemblyStore->Entries().Count()-1);
       
   710 
       
   711 	iReassemblyStore->BeginTransactionLC();
       
   712 	TInt count = iReassemblyStore->Entries().Count();
       
   713 
       
   714 	CSmsBuffer* buffer = CSmsBuffer::NewL();
       
   715 	CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, CSmsPDU::ESmsDeliver, buffer );
       
   716 	CleanupStack::PushL( smsMessage );
       
   717 
       
   718 	while (count--)
       
   719 		{
       
   720 		TSAREntry entry(iReassemblyStore->Entries()[count]);
       
   721 		if ( entry.IsComplete() )
       
   722 			{
       
   723 			TRAPD( ret, iReassemblyStore->GetMessageL( count , *smsMessage ) );
       
   724 			if ( ret == KErrNone )
       
   725 				{
       
   726 				if( !iReassemblyStore->PassedToClient( count ) )
       
   727 					{
       
   728 						if(!(aCurrentSmsMessage && aCurrentSmsMessage->Time()==smsMessage->Time()))
       
   729 						{
       
   730 						TBuf16<CSmsPDUProcessor::ESmsMaxDeliverReportBufferSize> buffer;
       
   731 						ret = aSmsComm.ProcessMessageL( *smsMessage, NULL, NULL, buffer );
       
   732 						if ( ret == KErrNone )
       
   733 							iReassemblyStore->SetPassedToClientL( count , ETrue);
       
   734 						}
       
   735 					}
       
   736 				}
       
   737 			}
       
   738 		}
       
   739 	CleanupStack::PopAndDestroy( smsMessage );
       
   740 	iReassemblyStore->CommitTransactionL();
       
   741 	}
       
   742 
       
   743 /**
       
   744 It searches the class 0 reassembly store for complete messages and then 
       
   745 it sends that message for further processing. It is called when a new 
       
   746 observer is added or a PDU has been received and successfully processed.
       
   747 
       
   748 @param aSmsComm  a reference to the protocol.
       
   749 @param aCurrentSmsMessage	a pointer to current SMS message.
       
   750 
       
   751 @internalComponent
       
   752 */
       
   753 void CFacadeSmsReassemblyStore::ProcessCompleteClass0SmsMessagesL(MSmsComm& aSmsComm, const CSmsMessage* aCurrentSmsMessage)
       
   754 	{
       
   755 	LOGSMSPROT2("CFacadeSmsReassemblyStore::ProcessCompleteClass0SmsMessagesL [from %d to 0]", iClass0ReassemblyStore->Entries().Count()-1);
       
   756 
       
   757 	iClass0ReassemblyStore->BeginTransactionLC();
       
   758 	TInt count = iClass0ReassemblyStore->Entries().Count();
       
   759 
       
   760 	CSmsBuffer* buffer = CSmsBuffer::NewL();
       
   761 	CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, CSmsPDU::ESmsDeliver, buffer );
       
   762 	CleanupStack::PushL( smsMessage );
       
   763 
       
   764 	while (count--)
       
   765 		{
       
   766 		TReassemblyEntry entry(iClass0ReassemblyStore->Entries()[count]);
       
   767 		if ( entry.IsComplete() )
       
   768 			{
       
   769 			TRAPD( ret, iClass0ReassemblyStore->GetMessageL( count , *smsMessage ) );
       
   770 			if ( ret == KErrNone )
       
   771 				{
       
   772 				if( !entry.PassedToClient() )
       
   773 					{
       
   774 						if(!(aCurrentSmsMessage && aCurrentSmsMessage->Time()==smsMessage->Time()))
       
   775 						{
       
   776 						TBuf16<CSmsPDUProcessor::ESmsMaxDeliverReportBufferSize> buffer;
       
   777 						ret = aSmsComm.ProcessMessageL( *smsMessage, NULL, NULL, buffer );
       
   778 						if ( ret == KErrNone )
       
   779 							iClass0ReassemblyStore->SetPassedToClientL(entry, ETrue);
       
   780 						}
       
   781 					}
       
   782 				}
       
   783 			}
       
   784 		}
       
   785 	CleanupStack::PopAndDestroy( smsMessage );
       
   786 	iClass0ReassemblyStore->CommitTransactionL();
       
   787 	//Call this function to process those messages whose time has expired.
       
   788 	iClass0ReassemblyStore->ProcessTimeoutMessageL();
       
   789 	iClass0ReassemblyStore->CleanReassemblyEntries();
       
   790 	}
       
   791 
       
   792 /**
       
   793 It externalizes all the enumerated messages.
       
   794 It goes through the re-assembly store and sends all those SMS messages 
       
   795 (which is SIM/Combined storage based) to client (aSmsProvider).
       
   796 
       
   797 @param aSmsProvider  a reference to a service access point.
       
   798 @param aCount	number of sms messages enumerated.
       
   799 @return number of new segments.
       
   800 
       
   801 @internalComponent
       
   802 */
       
   803 TInt CFacadeSmsReassemblyStore::ExternalizeEnumeratedNonClass0SmsMessagesL(CSmsProvider& aProvider,TInt& aCount)
       
   804 	{
       
   805 	LOGSMSPROT1("CFacadeSmsReassemblyStore::ExternalizeEnumeratedNonClass0SmsMessagesL()");
       
   806 	TInt count = iReassemblyStore->Entries().Count();
       
   807 	TInt index,numNewSegments(0);
       
   808 	for(index = count-1; index >=0; --index)
       
   809 		{
       
   810 		TSmsReassemblyEntry entry= (TSmsReassemblyEntry&) iReassemblyStore->Entries()[index];
       
   811 		if( entry.PassedToClient() == EFalse)
       
   812 			{
       
   813 			CSmsPDU::TSmsPDUType pdu = entry.PduType();
       
   814 			CSmsBuffer* buffer = CSmsBuffer::NewL();
       
   815 			CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, pdu, buffer );
       
   816 			CleanupStack::PushL(smsMessage);
       
   817 			iReassemblyStore->GetMessageL(index,*smsMessage);
       
   818 			if (((smsMessage->Storage() == CSmsMessage::ESmsSIMStorage) || (smsMessage->Storage() == CSmsMessage::ESmsCombinedStorage)) ||
       
   819                 ( (smsMessage->DecodedOnSim()) && (smsMessage->ForwardToClient())  ) )
       
   820 				{
       
   821 				numNewSegments+=aProvider.ExternalizeMessageL(*smsMessage,EFalse);
       
   822 				for(TInt i=0; i< smsMessage->iSlotArray.Count() ;i++)
       
   823 					{
       
   824 					LOGSMSPROT2("CFacadeSmsReassemblyStore::ExternalizeEnumeratedNonClass0SmsMessagesL %d", smsMessage->iSlotArray[i].iIndex);
       
   825 					}
       
   826 				++aCount;
       
   827 				iReassemblyStore->BeginTransactionLC();
       
   828 				iReassemblyStore->SetPassedToClientL(index,ETrue);
       
   829 				iReassemblyStore->CommitTransactionL();
       
   830 				}
       
   831 			CleanupStack::PopAndDestroy(smsMessage);
       
   832 			}
       
   833 		}
       
   834 	return numNewSegments;
       
   835 	}
       
   836 
       
   837 /**
       
   838 It externalizes all the class 0 enumerated messages.
       
   839 It goes through the class 0 re-assembly store and sends all those SMS messages 
       
   840 (which is SIM/Combined storage based) to client (aSmsProvider).
       
   841 
       
   842 @param aSmsProvider  a reference to a service access point.
       
   843 @param aCount	number of sms messages enumerated.
       
   844 @return number of new segments.
       
   845 
       
   846 @internalComponent
       
   847 */
       
   848 TInt CFacadeSmsReassemblyStore::ExternalizeEnumeratedClass0SmsMessagesL(CSmsProvider& aProvider,TInt& aCount)
       
   849 	{
       
   850 	LOGSMSPROT1("CFacadeSmsReassemblyStore::ExternalizeEnumeratedClass0SmsMessagesL()");
       
   851 	TInt count = iClass0ReassemblyStore->Entries().Count();
       
   852 	TInt index,numNewSegments(0);
       
   853 	for(index = count-1; index >=0; --index)
       
   854 		{
       
   855 		TReassemblyEntry entry= (TReassemblyEntry&) iClass0ReassemblyStore->Entries()[index];
       
   856 		if( entry.PassedToClient() == EFalse)
       
   857 			{
       
   858 			CSmsPDU::TSmsPDUType pdu = entry.PduType();
       
   859 			CSmsBuffer* buffer = CSmsBuffer::NewL();
       
   860 			CSmsMessage* smsMessage = CSmsMessage::NewL(iFs, pdu, buffer );
       
   861 			CleanupStack::PushL(smsMessage);
       
   862 			iClass0ReassemblyStore->GetMessageL(index,*smsMessage);
       
   863 			if (((smsMessage->Storage() == CSmsMessage::ESmsSIMStorage) || (smsMessage->Storage() == CSmsMessage::ESmsCombinedStorage)) ||
       
   864                 ( (smsMessage->DecodedOnSim()) && (smsMessage->ForwardToClient())  ) )
       
   865 				{
       
   866 				numNewSegments+=aProvider.ExternalizeMessageL(*smsMessage,EFalse);
       
   867 				for(TInt i=0; i< smsMessage->iSlotArray.Count() ;i++)
       
   868 					{
       
   869 					LOGSMSPROT2("CFacadeSmsReassemblyStore::ExternalizeEnumeratedClass0SmsMessagesL() %d", smsMessage->iSlotArray[i].iIndex);
       
   870 					}
       
   871 				++aCount;
       
   872 				iClass0ReassemblyStore->BeginTransactionLC();
       
   873 				iClass0ReassemblyStore->SetPassedToClientL(entry, ETrue);
       
   874 				iClass0ReassemblyStore->CommitTransactionL();
       
   875 				}
       
   876 			CleanupStack::PopAndDestroy(smsMessage);
       
   877 			}
       
   878 		}
       
   879 	return numNewSegments;
       
   880 	}
       
   881 
       
   882 /**
       
   883 It adds the message segment to the general reassembly store.
       
   884 
       
   885 @note Only SUBMIT or DELIVER PDUs can be added to the reassembly store.
       
   886 
       
   887 @param aSmsMessage  a reference to the SMS message.
       
   888 	It acts both as input & output. At the time of function call it contains the message.
       
   889 	When the function returns it contains full decoded message.
       
   890 
       
   891 @param aGsmSms	a reference to GsmSms object which contain actual PDU.
       
   892 	It acts as pure input.
       
   893 
       
   894 @param aIsComplete  boolean value indicating whether the message is complete or not.
       
   895 	It acts both as input & output.
       
   896 	In case of multi-segment message, the value of aIsComplete will be true when function returns 
       
   897 	if the added segment makes the messsage complete.
       
   898 
       
   899 @param aIsEnumeration	boolean value indicating whether the function is called at the time of enumeration.
       
   900 	It acts as only input.
       
   901 
       
   902 @param aCount  value indicating the number of current PDUs in the re-assembly store for the given SMS message.
       
   903 	It acts as only output.
       
   904 
       
   905 @param aTotal	value indicating the total number of PDUs for the given sms message.
       
   906 	It acts as only output.
       
   907 
       
   908 @internalComponent
       
   909 
       
   910 NOTE:
       
   911 	When function returns, if the value of aIsComplete is True, then aSmsMesssage will contain the
       
   912 	complete decoded SMS message.
       
   913 */
       
   914 void CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(CSmsMessage& aSmsMessage,const TGsmSms& aGsmSms, TInt& aIndex, TBool& aIsComplete, TBool aIsEnumeration, TInt& aCount, TInt& aTotal)
       
   915 	{
       
   916 	LOGSMSPROT2("CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(): isComplete Message=%d",
       
   917 				aSmsMessage.IsComplete());
       
   918 
       
   919 	if (aIsComplete ||  aSmsMessage.Type() == CSmsPDU::ESmsStatusReport)
       
   920 		{
       
   921 		//
       
   922 		// 1) This is the complete message (e.g. a single-segment message).
       
   923 		//    We therefore have all the segments.
       
   924 		//
       
   925 		// Create the new message in the reassembly store. This is incase the
       
   926 		// power fails before the client gets it (note that it will be ack'd
       
   927 		// before passed to the client) so keeping it in memory is not
       
   928 		// acceptable...
       
   929 		//
       
   930 		iReassemblyStore->NewMessagePDUL(aIndex, aSmsMessage, aGsmSms);
       
   931 		}
       
   932 	else
       
   933 		{
       
   934 		//
       
   935 		// If not yet complete, then we must be part of a multiple PDU message.
       
   936 		// Search the reassembly store for existing parts of the message.
       
   937 		//
       
   938 		TInt  segStoreIndex(KErrNotFound);
       
   939 
       
   940 		iReassemblyStore->MatchPDUToExistingMessage(aSmsMessage, segStoreIndex);
       
   941 		LOGSMSPROT2("CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(): "
       
   942 					"segStoreIndex=%d", segStoreIndex);
       
   943 
       
   944 		//
       
   945 		// If not yet complete, then we must be part of a multiple PDU message.
       
   946 		// Search the reassembly store for existing parts of the message. This
       
   947 		// may set iIsComplete to true if all segments are then found.
       
   948 		//
       
   949 		if (segStoreIndex != KErrNotFound)
       
   950 		 	{
       
   951 			TBool  isDuplicateSlot;
       
   952 			TBool  isDuplicateMsgRef;
       
   953 		 	//
       
   954 		 	// So we found a related part of the message, add this message to the
       
   955 		 	// store...
       
   956 		 	//
       
   957 		 	aIndex = segStoreIndex;
       
   958 			iReassemblyStore->UpdateExistingMessageL(aSmsMessage, aGsmSms, aIndex,
       
   959 													aIsComplete, isDuplicateMsgRef,
       
   960 													isDuplicateSlot);
       
   961 			LOGSMSPROT5("CFacadeSmsReassemblyStore::AddSegmentToNonClass0ReassemblyStoreL(): "
       
   962 						"aIndex=%d, isComplete=%d, isDuplicateMsgRef=%d, isDuplicateSlot=%d",
       
   963 						aIndex, aIsComplete, isDuplicateMsgRef, isDuplicateSlot);
       
   964 
       
   965 			if (isDuplicateMsgRef)
       
   966 				{
       
   967 				//
       
   968 				// In most cases discard it, unless we are doing an enumeration???
       
   969 				//
       
   970 				if (aIsEnumeration)
       
   971 					{
       
   972 					iReassemblyStore->NewMessagePDUL(aIndex, aSmsMessage, aGsmSms);
       
   973 					}
       
   974 				}
       
   975 			else if (aIsComplete)
       
   976 				{
       
   977 				//
       
   978 				// 3) This is the last segment in the message required to complete it.
       
   979 				//    The other segments are already stored.
       
   980 				//
       
   981 				// Load the complete message into memory for futher processing.
       
   982 				//
       
   983 				iReassemblyStore->GetMessageL(aIndex, aSmsMessage);
       
   984 				}
       
   985 			else
       
   986 				{
       
   987 				//
       
   988 				// 4) This is another PDU to an existing message in the store, but it is
       
   989 				//    not yet complete.
       
   990 				//
       
   991 				// Update the this segment with the timestamp of the original message.
       
   992 				//
       
   993 				CSmsBuffer*  buffer = CSmsBuffer::NewL();
       
   994 				CSmsMessage*  firstMessagePdu = CSmsMessage::NewL(FileSession(),
       
   995 																  CSmsPDU::ESmsDeliver, buffer);
       
   996 				CleanupStack::PushL(firstMessagePdu);
       
   997 				iReassemblyStore->GetMessageL(aIndex, *firstMessagePdu);
       
   998 				aSmsMessage.SetUTCOffset(firstMessagePdu->UTCOffset());
       
   999 				CleanupStack::PopAndDestroy(firstMessagePdu);
       
  1000 				}
       
  1001 			}
       
  1002 		else
       
  1003 			{
       
  1004 			//
       
  1005 			// 5) This is the first PDU in the message, and therefore the message is
       
  1006 			//    not yet complete and no segments are stored.
       
  1007 			//
       
  1008 			// The entry needs to be added to the reassembly store as a new entry.
       
  1009 			//
       
  1010 			iReassemblyStore->NewMessagePDUL(aIndex, aSmsMessage, aGsmSms);
       
  1011 			}
       
  1012 		}
       
  1013 
       
  1014 	//
       
  1015 	// Update the Log Server ID and time data from the other segments.
       
  1016 	//
       
  1017 	const TSAREntry&  entry = iReassemblyStore->Entries()[aIndex];
       
  1018 
       
  1019 	aSmsMessage.SetLogServerId(entry.LogServerId());
       
  1020 	aSmsMessage.SetTime(entry.Time());
       
  1021 
       
  1022 	aCount = entry.Count();
       
  1023 	aTotal = entry.Total();
       
  1024 	}
       
  1025 
       
  1026 /**
       
  1027 It updates log server id of the passed message in re-assembly store.
       
  1028 
       
  1029 @param aSmsMessage  a reference to a message.
       
  1030 @param aIndex	index number of sms message to be updated.
       
  1031 
       
  1032 @internalComponent
       
  1033 */
       
  1034 void CFacadeSmsReassemblyStore::UpdateLogServerIdOfNonClass0MessageL(const CSmsMessage& aSmsMessage, TInt aIndex)
       
  1035 	{
       
  1036 	//
       
  1037 	// Find the message in the reassembly store...
       
  1038 	//
       
  1039     TInt  foundIndex(KErrNotFound);
       
  1040 	TBool  found(EFalse);
       
  1041     
       
  1042 	if (iReassemblyStore->InTransaction())
       
  1043 		{
       
  1044 		found = iReassemblyStore->FindMessageL(aSmsMessage, EFalse, foundIndex);
       
  1045 		}
       
  1046 	else
       
  1047 		{
       
  1048 		iReassemblyStore->BeginTransactionLC();
       
  1049 		found = iReassemblyStore->FindMessageL(aSmsMessage, EFalse, foundIndex);
       
  1050 		iReassemblyStore->CommitTransactionL();
       
  1051 		}
       
  1052 
       
  1053 	LOGSMSPROT3("CFacadeSmsReassemblyStore::UpdateLogServerIdOfNonClass0MessageL(): found=%d, foundIndex=%d",
       
  1054 				found, foundIndex);
       
  1055 
       
  1056 	//
       
  1057 	// If found and the index is valid, then update the Log Server ID...
       
  1058 	//
       
  1059 	if (found  &&  aIndex == foundIndex)
       
  1060 		{
       
  1061 		iReassemblyStore->UpdateLogServerIdL(aIndex,
       
  1062 											aSmsMessage.LogServerId());
       
  1063 		}
       
  1064 	}
       
  1065 
       
  1066 /**
       
  1067  *  Checks whether a message is a WAP message.
       
  1068  *  
       
  1069  */
       
  1070 TBool CFacadeSmsReassemblyStore::IsWapSMS(const CSmsMessage& aSmsMessage)
       
  1071 	{
       
  1072 	LOGSMSPROT1("CFacadeSmsReassemblyStore::IsWapSMS()");
       
  1073 
       
  1074 	return CSmsProtocol::IsAppPortSMS(aSmsMessage);
       
  1075 	}