smsprotocols/smsstack/wapprot/Src/wappstor.cpp
changeset 0 3553901f7fa8
child 14 7ef16719d8cb
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 1997-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 "wappstor.h"
       
    17 #include "ws_main.h"
       
    18 #include "smsstackutils.h"
       
    19 
       
    20 
       
    21 _LIT(KStoreName,"wapreast.dat");
       
    22 
       
    23 const TInt KWapReassemblyStoreUidValue=0x100008CB;
       
    24 const TUid KWapReassemblyStoreUid={KWapReassemblyStoreUidValue};  //  Used for second uid of SAR stores
       
    25 
       
    26 
       
    27 CWapReassemblyStore* CWapReassemblyStore::NewL(RFs& aFs)
       
    28     {
       
    29     LOGWAPPROT1("CWapReassemblyStore::NewL()");
       
    30 
       
    31     CWapReassemblyStore* reassembly=new (ELeave)CWapReassemblyStore(aFs);
       
    32    	CleanupStack::PushL(reassembly);
       
    33 	reassembly->ConstructL();
       
    34 	CleanupStack::Pop(reassembly);
       
    35     return reassembly;
       
    36     } // CWapReassemblyStore::NewL
       
    37 
       
    38 
       
    39 CWapReassemblyStore::~CWapReassemblyStore()
       
    40     {
       
    41     this->Close();
       
    42     }
       
    43 
       
    44 
       
    45 TBool CWapReassemblyStore::AddMessageL( TInt& aIndex, const CWapDatagram& aDatagram)                                                
       
    46     {
       
    47     LOGWAPPROT1("CWapReassemblyStore::AddMessageL()");
       
    48 
       
    49     CArrayPtrFlat<CWapDatagram::TSegmentData>* segmentArray = new
       
    50         (ELeave) CArrayPtrFlat<CWapDatagram::TSegmentData> (8);
       
    51 
       
    52     CleanupStack::PushL(segmentArray);
       
    53     CleanupResetAndDestroyPushL(*segmentArray);
       
    54     
       
    55     TBool isComplete = aDatagram.IsComplete();
       
    56 
       
    57     // count of incomplete WAP short messages
       
    58     TInt Count = Entries().Count();
       
    59     if (!isComplete)
       
    60         {
       
    61         TWapReassemblyEntry Entry;
       
    62         TBool     isFound = EFalse;
       
    63 
       
    64         // go through all entries in the reassembly store
       
    65         // and find the short message entry,
       
    66         // which matches with the given entry
       
    67         for(aIndex=0;aIndex<Count; aIndex++)
       
    68             {
       
    69             TInt ToPort = 0;
       
    70             TInt FromPort = 0;
       
    71             aDatagram.Ports(FromPort,ToPort);
       
    72             Entry = (TWapReassemblyEntry&)Entries()[aIndex];
       
    73             isFound =    ((Entry.Reference() ==
       
    74                              aDatagram.ConcatenatedMessageReference())
       
    75                       && (Entry.Total() ==
       
    76                              aDatagram.NumConcatenatedMessages())
       
    77                       && (Entry.ToPort() == ToPort)
       
    78                       && (Entry.Description1() ==
       
    79                              aDatagram.FromAddress()));
       
    80             if (isFound)
       
    81                 break;
       
    82             }
       
    83         if (isFound)
       
    84             {
       
    85             isFound = EFalse;
       
    86 
       
    87             // new short message fragment received for an existing
       
    88             // incomplete WAP datagram
       
    89             TStreamId StreamdId = Entry.DataStreamId();
       
    90             CWapDatagram* tempDatagram = CWapDatagram::NewL(KNullDesC8);
       
    91             CleanupStack::PushL(tempDatagram);
       
    92 
       
    93             // defect fix for EDNJJUN-4WYJGP
       
    94             // Unable to send sms cause sms*.dat is corrupted
       
    95             // TODO - has to be back ported to higher versions
       
    96             TRAPD(ret, InternalizeEntryL(StreamdId,*tempDatagram,*segmentArray));
       
    97             if(ret == KErrCorrupt)
       
    98                 {
       
    99                 Close();
       
   100                 User::LeaveIfError(iFs.Delete(iFullPathBuf));
       
   101                 DoOpenL();        //create a new file
       
   102                 }
       
   103             else
       
   104                 User::LeaveIfError(ret);
       
   105 
       
   106             // For the first: discard duplicates
       
   107             // It takes place by comparing indexes of TSegmentDatas
       
   108             CWapDatagram::TSegmentData *segmentData = new (ELeave)CWapDatagram::TSegmentData;
       
   109             CleanupStack::PushL(segmentData);
       
   110             aDatagram.SegmentData(*segmentData);
       
   111 
       
   112             if(aDatagram.NumConcatenatedMessages() < segmentData->iSegmentNumber)
       
   113             {
       
   114                 isFound = ETrue;                // out of range discard
       
   115                 CleanupStack::PopAndDestroy(segmentData);
       
   116             }
       
   117             else
       
   118             {
       
   119                 Count=segmentArray->Count();
       
   120                 for (TInt i=0; i<Count; i++)
       
   121                     {
       
   122                     CWapDatagram::TSegmentData* thisSegmentData =
       
   123                                segmentArray->At(i);
       
   124                 if (thisSegmentData->iSegmentNumber
       
   125                         == segmentData->iSegmentNumber)
       
   126                     {
       
   127                     // duplicate found. It is not saved.
       
   128                     isFound = ETrue;
       
   129                     CleanupStack::PopAndDestroy(segmentData);
       
   130                     break;
       
   131                     }
       
   132                 }
       
   133             }
       
   134             if (!isFound)
       
   135                 {
       
   136                 TInt j=0;
       
   137                 for (; (j<segmentArray->Count()) && (segmentData->iSegmentNumber>(*segmentArray)[j]->iSegmentNumber); j++)
       
   138                 {
       
   139                 }
       
   140                 segmentArray->InsertL(j,segmentData);
       
   141                 CleanupStack::Pop(segmentData);
       
   142                 if (segmentArray->Count() ==
       
   143                         aDatagram.NumConcatenatedMessages())
       
   144                     // all fragments of a datagram are available
       
   145                     isComplete = ETrue;
       
   146 
       
   147                 BeginTransactionLC();
       
   148                 ExternalizeEntryL(StreamdId,*tempDatagram,*segmentArray);
       
   149                 PopulateEntry(Entry,*tempDatagram,segmentArray->Count());
       
   150                 ChangeEntryL(aIndex,Entry);
       
   151                 CommitTransactionL();
       
   152                 }
       
   153             CleanupStack::PopAndDestroy(tempDatagram);
       
   154             }
       
   155             // else - a duplicate was found. Ignored.
       
   156         else
       
   157             {
       
   158             // a first short message fragment received for a
       
   159             // non-existing WAP datagram
       
   160             CWapDatagram::TSegmentData *segmentData = new (ELeave)CWapDatagram::TSegmentData;
       
   161             CleanupStack::PushL(segmentData);
       
   162             aDatagram.SegmentData(*segmentData);
       
   163             if(aDatagram.NumConcatenatedMessages() < segmentData->iSegmentNumber)
       
   164                 {
       
   165                 CleanupStack::PopAndDestroy(segmentData);
       
   166                 isComplete=EFalse;
       
   167                 }
       
   168             else
       
   169                 {
       
   170                 segmentArray->AppendL(segmentData);
       
   171                 CleanupStack::Pop(segmentData);
       
   172                     aIndex = Count;
       
   173                 CreateEntryL(aDatagram,*segmentArray);
       
   174                 }
       
   175             }
       
   176         }
       
   177     else // the datagram is complete
       
   178         {
       
   179         CWapDatagram::TSegmentData *segmentData = new (ELeave)CWapDatagram::TSegmentData;
       
   180         CleanupStack::PushL(segmentData);
       
   181         aDatagram.SegmentData(*segmentData);
       
   182         if(aDatagram.NumConcatenatedMessages() < segmentData->iSegmentNumber)
       
   183             {
       
   184             CleanupStack::PopAndDestroy(segmentData);
       
   185             isComplete=EFalse;
       
   186             }
       
   187         else
       
   188             {
       
   189             segmentArray->AppendL(segmentData);
       
   190             CleanupStack::Pop(segmentData);
       
   191             aIndex = Count;
       
   192             CreateEntryL(aDatagram,*segmentArray);
       
   193             }
       
   194         }
       
   195 
       
   196     CleanupStack::PopAndDestroy(2, segmentArray);  // segmentArray elements (Reset and Destroy), segmentArray
       
   197     return isComplete;
       
   198     } // CWapReassemblyStore::AddMessageL
       
   199 
       
   200 void CWapReassemblyStore::GetDatagramL( TInt            aIndex,
       
   201                                                 CWapDatagram&   aDatagram)
       
   202     {
       
   203     LOGWAPPROT1("CWapReassemblyStore::GetDatagramL()");
       
   204 
       
   205     CArrayPtrFlat<CWapDatagram::TSegmentData>* segmentArray = new
       
   206         (ELeave) CArrayPtrFlat<CWapDatagram::TSegmentData> (8);
       
   207     
       
   208     // here we need to push 'segmentArray' pointer to the cleanup stack, since it's a heap allocation (pointer must be deleted)
       
   209     // CleanupResetAndDestroyPushL() just trigers ResetAndDestroy() to be called on CleanupStack::PopAndDestroy()     
       
   210     CleanupStack::PushL(segmentArray);
       
   211     CleanupResetAndDestroyPushL(*segmentArray);
       
   212 
       
   213     // defect fix for EDNJJUN-4WYJGP
       
   214     // Unable to send sms cause sms*.dat is corrupted
       
   215     // TODO - has to be back ported to higher versions
       
   216     TRAPD(ret, InternalizeEntryL(Entries()[aIndex].DataStreamId(), aDatagram,*segmentArray));
       
   217     if(ret == KErrCorrupt)
       
   218         {
       
   219         Close();             //because the file is in use
       
   220         User::LeaveIfError(iFs.Delete(iFullPathBuf));
       
   221         DoOpenL();        //create a new file
       
   222         }
       
   223     else
       
   224         User::LeaveIfError(ret);
       
   225 
       
   226     if(aDatagram.Alphabet() == TSmsDataCodingScheme::ESmsAlphabet7Bit)
       
   227         {
       
   228         aDatagram.DecodeConcatenatedMessagesL(*segmentArray);
       
   229         }
       
   230 
       
   231     CleanupStack::PopAndDestroy(2, segmentArray);  // segmentArray elements (Reset and Destroy), segmentArray
       
   232     } // CWapReassemblyStore::GetDatagramL
       
   233 
       
   234 TBool CWapReassemblyStore::FindAndDeleteDatagramL( CWapDatagram& aDatagram)
       
   235 	{
       
   236 	LOGWAPPROT1("CWapReassemblyStore::FindAndDeleteDatagramL()");
       
   237 
       
   238 	TInt index;
       
   239 	TBool isFound = EFalse;
       
   240 	TWapReassemblyEntry entry;
       
   241 	TInt toPort = 0;
       
   242     TInt fromPort = 0;
       
   243     aDatagram.Ports(fromPort,toPort);
       
   244 
       
   245 	TInt Count = Entries().Count();
       
   246 	for(index=0;index<Count; index++)
       
   247             {
       
   248             entry = (TWapReassemblyEntry&)Entries()[index];
       
   249             isFound =    ((entry.Reference() ==
       
   250                              aDatagram.ConcatenatedMessageReference())
       
   251                       && (entry.ToPort() == toPort)
       
   252 					  &&(entry.Total() ==
       
   253                              aDatagram.NumConcatenatedMessages()));
       
   254 			if (isFound)
       
   255 				{
       
   256 				BeginTransactionLC();
       
   257 				DeleteEntryL(index);
       
   258 				CommitTransactionL();
       
   259 				return isFound;
       
   260 				}
       
   261 			}
       
   262 	return isFound;
       
   263 	} // CWapReassemblyStore::FindAndDeleteDatagramL
       
   264 
       
   265 
       
   266 void CWapReassemblyStore::ConstructL()
       
   267     {
       
   268     LOGWAPPROT1("CWapReassemblyStore::ConstructL()");
       
   269 
       
   270     //get full path of reassembly store
       
   271     PrivatePath(iFullPathBuf);
       
   272 	//append store name
       
   273 	iFullPathBuf.Append(KStoreName);
       
   274     OpenStoreL();
       
   275     } // CWapReassemblyStore::ConstructL
       
   276 
       
   277 
       
   278 /**
       
   279  *  internalize all the entries from the permanent file store to internal memory
       
   280  *  
       
   281  *  @note You have to call CSARStore::OpenFileLC() before calling this function
       
   282  *  @param aStreamId, unique id associated with the stream
       
   283  *  @param aDatagram, the datagram which will be internalized
       
   284  *  @param aSegmentArray, the array of segments for the datagram
       
   285  */
       
   286 void CWapReassemblyStore::InternalizeEntryL(
       
   287                             TStreamId                   aStreamId,
       
   288                             CWapDatagram&               aDatagram,
       
   289                             CArrayPtr<CWapDatagram::TSegmentData>&  aSegmentArray)
       
   290     {
       
   291     LOGWAPPROT1("CWapReassemblyStore::InternalizeEntryL Start");
       
   292 
       
   293 	BeginTransactionLC();
       
   294     RStoreReadStream ReadStream;
       
   295     TInt32 Count;
       
   296 
       
   297     ReadStream.OpenLC(FileStore(),aStreamId);
       
   298     ReadStream >> aDatagram;
       
   299 
       
   300 	if(aDatagram.Alphabet() == TSmsDataCodingScheme::ESmsAlphabet8Bit)
       
   301 		{
       
   302 		aDatagram.InternalizeBufferL(ReadStream);
       
   303 		}
       
   304     else
       
   305 		{
       
   306 		Count=ReadStream.ReadInt32L();
       
   307 
       
   308 		aSegmentArray.Reset();
       
   309 	    for (TInt i=0; i<Count; i++)
       
   310 		    {
       
   311 			CWapDatagram::TSegmentData* Segment = new (ELeave) CWapDatagram::TSegmentData;
       
   312 			CleanupStack::PushL(Segment);
       
   313 			aSegmentArray.AppendL(Segment);
       
   314 			CleanupStack::Pop();
       
   315 
       
   316 			Segment->iSegmentNumber = ReadStream.ReadInt32L();
       
   317 			ReadStream >> Segment->iData;
       
   318 			}
       
   319 		}
       
   320     // Closes the ReadStream
       
   321     CleanupStack::PopAndDestroy();
       
   322 	CommitTransactionL();
       
   323     LOGWAPPROT1("CWapReassemblyStore::InternalizeEntryL End");
       
   324     } // CWapReassemblyStore::InternalizeEntryL
       
   325 
       
   326 
       
   327 /**
       
   328  *  externalizes all the entries from the internal memory to the permanent file store
       
   329  *  
       
   330  *  @note You have to call CSARStore::OpenFileLC() before calling this function
       
   331  *  @param aStreamId, unique id associated with the stream
       
   332  *  @param aDatagram, the datagram which should be externalized
       
   333  *  @param aSegmentArray, the array of segments for the datagram
       
   334  */
       
   335 void CWapReassemblyStore::ExternalizeEntryL(
       
   336                             TStreamId&          aStreamId,
       
   337                             const CWapDatagram& aDatagram,
       
   338                             const CArrayPtr<CWapDatagram::TSegmentData>& aSegmentArray)
       
   339     {
       
   340     LOGWAPPROT1("CWapReassemblyStore::ExternalizeEntryL Start");
       
   341     
       
   342     TInt32 Count = aSegmentArray.Count();
       
   343     RStoreWriteStream WriteStream;
       
   344 
       
   345     if (aStreamId==KNullStreamId)
       
   346         aStreamId=WriteStream.CreateLC(FileStore());
       
   347     else
       
   348         WriteStream.ReplaceLC(FileStore(),aStreamId);
       
   349     WriteStream<<aDatagram;
       
   350 
       
   351 	if(aDatagram.Alphabet() == TSmsDataCodingScheme::ESmsAlphabet8Bit)
       
   352 		{
       
   353 		aDatagram.ExternalizeBufferL(WriteStream);
       
   354 		}
       
   355     else
       
   356 		{
       
   357 		WriteStream.WriteInt32L(Count);
       
   358 		for(TInt i=0; i<Count; i++)
       
   359 			{
       
   360 			WriteStream.WriteInt32L(aSegmentArray[i]->iSegmentNumber);
       
   361 			WriteStream<<aSegmentArray[i]->iData;
       
   362 			}
       
   363 
       
   364 		}
       
   365 	// Closes the ReadStream
       
   366     WriteStream.CommitL();
       
   367     CleanupStack::PopAndDestroy();
       
   368     } // CWapReassemblyStore::ExternalizeEntryL
       
   369 
       
   370 
       
   371 void CWapReassemblyStore::PopulateEntry(TWapReassemblyEntry& aEntry,
       
   372                                         const CWapDatagram& aDatagram,
       
   373                                         TInt                aNumDatagrams)
       
   374     {
       
   375     LOGWAPPROT1("CWapReassemblyStore::PopulateEntry()");
       
   376 
       
   377     TInt ToPort = 0;
       
   378     TInt FromPort = 0;
       
   379 
       
   380     aDatagram.Ports(FromPort,ToPort);
       
   381             // complete or not complete
       
   382     if (!aDatagram.IsComplete())
       
   383         {
       
   384         aEntry.SetReference(aDatagram.ConcatenatedMessageReference());
       
   385         aEntry.SetTotal(aDatagram.NumConcatenatedMessages());
       
   386         aEntry.SetCount(aNumDatagrams);
       
   387         }
       
   388         else
       
   389         {
       
   390 		//Wap Datagram might contain reference number which will be 
       
   391 		//needed at the time of deleting the datagram from permanent store file
       
   392 		//Refer To Defect Fix: PDEF114607.
       
   393 		aEntry.SetReference(aDatagram.ConcatenatedMessageReference());
       
   394 		aEntry.SetTotal(1);
       
   395 		aEntry.SetCount(1);
       
   396         }
       
   397 
       
   398     aEntry.SetToPort(ToPort);
       
   399     aEntry.SetDescription1(aDatagram.FromAddress());
       
   400     aEntry.SetTime(aDatagram.Time());
       
   401     } // CWapReassemblyStore::PopulateEntry
       
   402 
       
   403 
       
   404 void CWapReassemblyStore::CreateEntryL(const CWapDatagram&                 aDatagram,
       
   405                                        const CArrayPtr<CWapDatagram::TSegmentData>& aSegmentArray)
       
   406 	{
       
   407 	LOGWAPPROT1("CWapReassemblyStore::CreateEntryL");
       
   408 
       
   409     TWapReassemblyEntry Entry;
       
   410     TStreamId WriteStream = KNullStreamId;
       
   411 	BeginTransactionLC();
       
   412     ExternalizeEntryL(WriteStream,aDatagram,aSegmentArray);
       
   413     Entry.SetDataStreamId(WriteStream);
       
   414     PopulateEntry(Entry,aDatagram,aDatagram.NumConcatenatedMessages());
       
   415     AddEntryL(Entry);
       
   416 	CommitTransactionL();
       
   417 	} // CWapReassemblyStore::CreateEntryL
       
   418 
       
   419 
       
   420 CWapReassemblyStore::CWapReassemblyStore(RFs& aFs)
       
   421     :CSARStore(aFs)
       
   422     {
       
   423     } // CWapReassemblyStore::CWapReassemblyStore
       
   424 
       
   425 
       
   426 /**
       
   427  *  Open the wap reassembly store.
       
   428  *  Use RFs::PrivatePath to generate private path.
       
   429  */
       
   430 void CWapReassemblyStore::OpenStoreL()
       
   431 	{
       
   432 	LOGWAPPROT1("CWapReassemblyStore::OpenStoreL()");
       
   433 
       
   434 	OpenL(iFullPathBuf,KWapReassemblyStoreUid);
       
   435 	} // CWapReassemblyStore::OpenStoreL
       
   436 
       
   437 // EOF - WAPPSTOR.CPP