cbs/cbsserver/ServerSrc/Ccbsreccollector.cpp
author hgs
Tue, 10 Aug 2010 13:19:41 +0300
changeset 38 bc103bfb69cf
parent 33 8d5d7fcf9b59
permissions -rw-r--r--
201031_02
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). 
hgs
parents:
diff changeset
     3
* All rights reserved.
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
*
hgs
parents:
diff changeset
     9
* Initial Contributors:
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
*
hgs
parents:
diff changeset
    12
* Contributors:
hgs
parents:
diff changeset
    13
*
hgs
parents:
diff changeset
    14
* Description:  This module contains the implementation of CCbsRecDecoder class 
hgs
parents:
diff changeset
    15
*                member functions.
hgs
parents:
diff changeset
    16
*    
hgs
parents:
diff changeset
    17
*                This class represents a collector, which stores pages of multipaged 
hgs
parents:
diff changeset
    18
*                messages. Complete messages are assembled and returned back to 
hgs
parents:
diff changeset
    19
*                the caller of CollectL() method.
hgs
parents:
diff changeset
    20
*  
hgs
parents:
diff changeset
    21
*                CCbsRecCollector stores message pages in a number of dynamic arrays.
hgs
parents:
diff changeset
    22
*                If all but one page of a message are present in collector, and
hgs
parents:
diff changeset
    23
*                the remaining page is received, the pages will be assembled and
hgs
parents:
diff changeset
    24
*                the corresponding message chain deleted.
hgs
parents:
diff changeset
    25
* 
hgs
parents:
diff changeset
    26
*                The maximum number of incomplete messages stored in collector at once
hgs
parents:
diff changeset
    27
*                is fixed and determined by KMaxCollectorMessages in CCbsRecCollector.cpp.
hgs
parents:
diff changeset
    28
* 
hgs
parents:
diff changeset
    29
*                CCbsRecCollector implements a circular list to contain message.
hgs
parents:
diff changeset
    30
*                Each incomplete message occupies a slot in this list. If the list already
hgs
parents:
diff changeset
    31
*                contains KMaxCollectorMessages messages, the next received multipaged
hgs
parents:
diff changeset
    32
*                message will delete all received pages of the oldest message in list.
hgs
parents:
diff changeset
    33
* 
hgs
parents:
diff changeset
    34
*                On receival of a message page, the collector compares network information
hgs
parents:
diff changeset
    35
*                (PLMN, LAC, CellId) of both messages to decide whether pages are of
hgs
parents:
diff changeset
    36
*                the same message. In short, for pages to be of the same message
hgs
parents:
diff changeset
    37
*                their network information have to meet the requirements set by the 
hgs
parents:
diff changeset
    38
*                geographical scope of the already collected page.
hgs
parents:
diff changeset
    39
*                See ETSI GSM 03.41 for a detailed description. 
hgs
parents:
diff changeset
    40
*
hgs
parents:
diff changeset
    41
*/
hgs
parents:
diff changeset
    42
hgs
parents:
diff changeset
    43
hgs
parents:
diff changeset
    44
// INCLUDE FILES
hgs
parents:
diff changeset
    45
#include "CbsServerPanic.h"
hgs
parents:
diff changeset
    46
#include "CCbsRecCollector.h"
hgs
parents:
diff changeset
    47
#include "CCbsRecMessage.h"
hgs
parents:
diff changeset
    48
#include "CCbsMessageFactory.h"
hgs
parents:
diff changeset
    49
#include "CCbsMessageCleanUpTimer.h"
hgs
parents:
diff changeset
    50
#include "CbsLogger.h"
hgs
parents:
diff changeset
    51
hgs
parents:
diff changeset
    52
// CONSTANTS
hgs
parents:
diff changeset
    53
hgs
parents:
diff changeset
    54
// Maximum number of pages in a single CB message.
hgs
parents:
diff changeset
    55
const TInt KMaxMessagePages = 15;
hgs
parents:
diff changeset
    56
hgs
parents:
diff changeset
    57
// Maximum number of partial messages contained in the collector list.
hgs
parents:
diff changeset
    58
const TInt KMaxCollectorMessages = 10;
hgs
parents:
diff changeset
    59
hgs
parents:
diff changeset
    60
// ================= MEMBER FUNCTIONS =======================
hgs
parents:
diff changeset
    61
hgs
parents:
diff changeset
    62
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    63
// CCbsRecCollector::CCbsRecCollector
hgs
parents:
diff changeset
    64
// C++ default constructor can NOT contain any code, that
hgs
parents:
diff changeset
    65
// might leave.
hgs
parents:
diff changeset
    66
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    67
//
hgs
parents:
diff changeset
    68
CCbsRecCollector::CCbsRecCollector( CCbsMessageFactory& aFactory )
hgs
parents:
diff changeset
    69
    : iRootNodeIterator( 0 ),
hgs
parents:
diff changeset
    70
    iFactory( aFactory )
hgs
parents:
diff changeset
    71
    {
hgs
parents:
diff changeset
    72
    }
hgs
parents:
diff changeset
    73
hgs
parents:
diff changeset
    74
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    75
// CCbsRecCollector::ConstructL
hgs
parents:
diff changeset
    76
// Symbian 2nd phase constructor can leave.
hgs
parents:
diff changeset
    77
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    78
//
hgs
parents:
diff changeset
    79
void CCbsRecCollector::ConstructL()
hgs
parents:
diff changeset
    80
    {
hgs
parents:
diff changeset
    81
    CBSLOGSTRING("CBSSERVER: >>> CCbsRecCollector::ConstructL()");
hgs
parents:
diff changeset
    82
hgs
parents:
diff changeset
    83
    // initialize the root node array
hgs
parents:
diff changeset
    84
    iRootNodeArray = new ( ELeave ) CArrayPtrFlat< CMessageBuffer >
hgs
parents:
diff changeset
    85
        ( KMaxCollectorMessages );
hgs
parents:
diff changeset
    86
    iRootNodeArray->SetReserveL( KMaxCollectorMessages );
hgs
parents:
diff changeset
    87
    iMessageCleanupTimerArray = new ( ELeave ) CArrayPtrFlat< CCbsMessageCleanupTimer >
hgs
parents:
diff changeset
    88
        ( KMaxCollectorMessages );
hgs
parents:
diff changeset
    89
hgs
parents:
diff changeset
    90
    for ( TInt i( 0 ); i < KMaxCollectorMessages; i++)
hgs
parents:
diff changeset
    91
        {
hgs
parents:
diff changeset
    92
        CMessageBuffer* array = new ( ELeave )
hgs
parents:
diff changeset
    93
            CMessageBuffer( KMaxMessagePages );
hgs
parents:
diff changeset
    94
        CleanupStack::PushL( array );
hgs
parents:
diff changeset
    95
        iRootNodeArray->AppendL( array );
hgs
parents:
diff changeset
    96
hgs
parents:
diff changeset
    97
		CCbsMessageCleanupTimer* messageCleanUpTimer = CCbsMessageCleanupTimer::NewL( *this, *array );
hgs
parents:
diff changeset
    98
		iMessageCleanupTimerArray->AppendL( messageCleanUpTimer );
hgs
parents:
diff changeset
    99
        
hgs
parents:
diff changeset
   100
        CleanupStack::Pop(); // array
hgs
parents:
diff changeset
   101
        }
hgs
parents:
diff changeset
   102
    CBSLOGSTRING("CBSSERVER: <<< CCbsRecCollector::ConstructL()");
hgs
parents:
diff changeset
   103
    }
hgs
parents:
diff changeset
   104
hgs
parents:
diff changeset
   105
hgs
parents:
diff changeset
   106
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   107
// CCbsRecCollector::NewL
hgs
parents:
diff changeset
   108
// Two-phased constructor.
hgs
parents:
diff changeset
   109
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   110
//
hgs
parents:
diff changeset
   111
 CCbsRecCollector* CCbsRecCollector::NewL( CCbsMessageFactory& aFactory )
hgs
parents:
diff changeset
   112
    {
hgs
parents:
diff changeset
   113
    CBSLOGSTRING("CBSSERVER: >>> CCbsRecCollector::NewL()");
hgs
parents:
diff changeset
   114
hgs
parents:
diff changeset
   115
    CCbsRecCollector* self = new ( ELeave ) CCbsRecCollector( aFactory );
hgs
parents:
diff changeset
   116
    CleanupStack::PushL( self );
hgs
parents:
diff changeset
   117
    self->ConstructL();
hgs
parents:
diff changeset
   118
    CleanupStack::Pop();
hgs
parents:
diff changeset
   119
hgs
parents:
diff changeset
   120
    CBSLOGSTRING("CBSSERVER: <<< CCbsRecCollector::NewL()");
hgs
parents:
diff changeset
   121
    return self;
hgs
parents:
diff changeset
   122
    }
hgs
parents:
diff changeset
   123
    
hgs
parents:
diff changeset
   124
// Destructor
hgs
parents:
diff changeset
   125
CCbsRecCollector::~CCbsRecCollector()
hgs
parents:
diff changeset
   126
    {
hgs
parents:
diff changeset
   127
    CBSLOGSTRING("CBSSERVER: >>> CCbsRecCollector::~CCbsRecCollector()");
hgs
parents:
diff changeset
   128
hgs
parents:
diff changeset
   129
    if ( iRootNodeArray )
hgs
parents:
diff changeset
   130
        {
hgs
parents:
diff changeset
   131
        TInt rootArrayLength( iRootNodeArray->Count() );
hgs
parents:
diff changeset
   132
        for ( TInt i( 0 ); i < rootArrayLength; i++ )
hgs
parents:
diff changeset
   133
            {
hgs
parents:
diff changeset
   134
            iRootNodeArray->At( i )->ResetAndDestroy();
hgs
parents:
diff changeset
   135
            }
hgs
parents:
diff changeset
   136
        iRootNodeArray->ResetAndDestroy();
hgs
parents:
diff changeset
   137
        delete iRootNodeArray;
hgs
parents:
diff changeset
   138
        }
hgs
parents:
diff changeset
   139
hgs
parents:
diff changeset
   140
    if ( iMessageCleanupTimerArray )
hgs
parents:
diff changeset
   141
        {
hgs
parents:
diff changeset
   142
        iMessageCleanupTimerArray->ResetAndDestroy();
hgs
parents:
diff changeset
   143
        delete iMessageCleanupTimerArray;
hgs
parents:
diff changeset
   144
        }
hgs
parents:
diff changeset
   145
hgs
parents:
diff changeset
   146
    CBSLOGSTRING("CBSSERVER: <<< CCbsRecCollector::~CCbsRecCollector()");
hgs
parents:
diff changeset
   147
    }
hgs
parents:
diff changeset
   148
hgs
parents:
diff changeset
   149
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   150
// CCbsRecCollector::CollectL
hgs
parents:
diff changeset
   151
// Adds a message to the location pointed by iRootNodeIterator.
hgs
parents:
diff changeset
   152
//   
hgs
parents:
diff changeset
   153
// Checks if all pages of message are present. If all pages
hgs
parents:
diff changeset
   154
// are present, sets aCompleted to ECbsMessageComplete,
hgs
parents:
diff changeset
   155
// combines message pages into a single message, destroys
hgs
parents:
diff changeset
   156
// pages from the list and returns the complete message
hgs
parents:
diff changeset
   157
// to caller in aMessage.
hgs
parents:
diff changeset
   158
hgs
parents:
diff changeset
   159
// Algorithm:
hgs
parents:
diff changeset
   160
//   1.  Check if other pages of this message exist in list.
hgs
parents:
diff changeset
   161
//       (serial number and message identifier match)
hgs
parents:
diff changeset
   162
//   2.  True: Check if the other messages in chain need
hgs
parents:
diff changeset
   163
//       to be deleted. This is based on geographical scope
hgs
parents:
diff changeset
   164
//       and network information.
hgs
parents:
diff changeset
   165
//       Add this message to the correct message chain.
hgs
parents:
diff changeset
   166
//       False: Add this message to the chain pointed
hgs
parents:
diff changeset
   167
//       by the iRootNodeIterator.
hgs
parents:
diff changeset
   168
//   3.  Seek out the position in the chosed message chain so that
hgs
parents:
diff changeset
   169
//       the page number sequence remains ordered (1, 2, .., n)
hgs
parents:
diff changeset
   170
//   4.  Add the page to the correct position in chain.
hgs
parents:
diff changeset
   171
//   5.  Check if all pages of this message exist (number count).
hgs
parents:
diff changeset
   172
//   6.  True: Combine message pages into a single message
hgs
parents:
diff changeset
   173
//       and return this page to the caller. Set aCompleted
hgs
parents:
diff changeset
   174
//       to ECbsMessageComplete.
hgs
parents:
diff changeset
   175
//       False: Set aCompleted to ECbsMessageIncomplete.
hgs
parents:
diff changeset
   176
//
hgs
parents:
diff changeset
   177
// Note: Ownership of aMessage assumed. aMessage assumed to be
hgs
parents:
diff changeset
   178
// on cleanup stack.
hgs
parents:
diff changeset
   179
// (other items were commented in a header).
hgs
parents:
diff changeset
   180
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   181
//  
hgs
parents:
diff changeset
   182
CCbsMessage* CCbsRecCollector::CollectL( 
hgs
parents:
diff changeset
   183
    CCbsMessage* aMessage, TInt aMessageType )  
hgs
parents:
diff changeset
   184
    {
hgs
parents:
diff changeset
   185
	CBSLOGSTRING("CBSSERVER: >>> CCbsRecCollector::CollectL()");
hgs
parents:
diff changeset
   186
hgs
parents:
diff changeset
   187
    // 1.
hgs
parents:
diff changeset
   188
    CMessageBuffer* array = FindChainContainingPage( *aMessage );
hgs
parents:
diff changeset
   189
    CCbsMessage* mergedMessage = NULL;
hgs
parents:
diff changeset
   190
hgs
parents:
diff changeset
   191
    if ( array  ) 
hgs
parents:
diff changeset
   192
        {		
hgs
parents:
diff changeset
   193
        CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): array != NULL");
hgs
parents:
diff changeset
   194
hgs
parents:
diff changeset
   195
        // 2. (True), 3.
hgs
parents:
diff changeset
   196
        __ASSERT_DEBUG( array->Count() > 0, 
hgs
parents:
diff changeset
   197
            CbsServerPanic( ECbsCollectorArrayEmpty ) );
hgs
parents:
diff changeset
   198
hgs
parents:
diff changeset
   199
        // Check geographical scope and network info to decide whether
hgs
parents:
diff changeset
   200
        // existing pages in this chain should be deleted.
hgs
parents:
diff changeset
   201
        TBool preserveExistingPages( 
hgs
parents:
diff changeset
   202
            CheckPageAreaInfoMatch( *aMessage, *array->At( 0 ) ) );
hgs
parents:
diff changeset
   203
		
hgs
parents:
diff changeset
   204
        CBSLOGSTRING2("CBSSERVER: CCbsRecCollector::CollectL(): preserveExistingPages: %d", preserveExistingPages );
hgs
parents:
diff changeset
   205
hgs
parents:
diff changeset
   206
        if ( preserveExistingPages ) 
hgs
parents:
diff changeset
   207
            {			
hgs
parents:
diff changeset
   208
            CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Adding msg to chain...");
hgs
parents:
diff changeset
   209
            // aMessage is deleted, if it is a duplicate.
hgs
parents:
diff changeset
   210
            AddMessageToChainL( aMessage, *array );			
hgs
parents:
diff changeset
   211
            CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Adding msg to chain OK.");
hgs
parents:
diff changeset
   212
            }
hgs
parents:
diff changeset
   213
        else 
hgs
parents:
diff changeset
   214
            {			
hgs
parents:
diff changeset
   215
            CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Deleting chain...");
hgs
parents:
diff changeset
   216
            DeleteChainL( *array );			
hgs
parents:
diff changeset
   217
            CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Deleting chain OK.");
hgs
parents:
diff changeset
   218
            array->InsertL( 0, aMessage );			
hgs
parents:
diff changeset
   219
            CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Msg added to array.");
hgs
parents:
diff changeset
   220
            }
hgs
parents:
diff changeset
   221
        // aMessage, ownership transferred to msg chain or
hgs
parents:
diff changeset
   222
        // aMessage has been deleted by AddMessageToChainL
hgs
parents:
diff changeset
   223
        CleanupStack::Pop(); 
hgs
parents:
diff changeset
   224
hgs
parents:
diff changeset
   225
        // 5. Check if this chain contains all pages of the message.
hgs
parents:
diff changeset
   226
        if ( AllPagesPresent( *array ) )
hgs
parents:
diff changeset
   227
            {			
hgs
parents:
diff changeset
   228
            CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): All pages present, merging...");
hgs
parents:
diff changeset
   229
hgs
parents:
diff changeset
   230
            // 6. merge creates a new copy of this message
hgs
parents:
diff changeset
   231
            // leaves a pointer to msg to cleanup stack
hgs
parents:
diff changeset
   232
            mergedMessage = MergePagesLC( *array ); // on CS			
hgs
parents:
diff changeset
   233
            CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Merging OK.");
hgs
parents:
diff changeset
   234
hgs
parents:
diff changeset
   235
			// we stop timer if its livecast message
hgs
parents:
diff changeset
   236
			if ( aMessageType == ECbsMessageLivecast )
hgs
parents:
diff changeset
   237
				{				
hgs
parents:
diff changeset
   238
                CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Msg type == ECbsMessageLivecast, stopping timer.");
hgs
parents:
diff changeset
   239
hgs
parents:
diff changeset
   240
				TKeyArrayFix key(0, ECmpTUint16);
hgs
parents:
diff changeset
   241
				TInt index;
hgs
parents:
diff changeset
   242
				iRootNodeArray->Find( array, key, index);
hgs
parents:
diff changeset
   243
				iMessageCleanupTimerArray->At( index )->StopTimer();
hgs
parents:
diff changeset
   244
                
hgs
parents:
diff changeset
   245
                CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Timer stopped.");
hgs
parents:
diff changeset
   246
				}
hgs
parents:
diff changeset
   247
hgs
parents:
diff changeset
   248
			CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Deleting chain...");
hgs
parents:
diff changeset
   249
            DeleteChainL( *array );
hgs
parents:
diff changeset
   250
			CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Deleting chain OK.");
hgs
parents:
diff changeset
   251
hgs
parents:
diff changeset
   252
            CleanupStack::Pop(); // mergedMessage
hgs
parents:
diff changeset
   253
            }
hgs
parents:
diff changeset
   254
        }
hgs
parents:
diff changeset
   255
    else
hgs
parents:
diff changeset
   256
        {		
hgs
parents:
diff changeset
   257
        CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): array == NULL");
hgs
parents:
diff changeset
   258
hgs
parents:
diff changeset
   259
		// if message pagenumber does not start from 1, its not inserted to chain.
hgs
parents:
diff changeset
   260
		if ( aMessage->ThisPage () == 1 ) 
hgs
parents:
diff changeset
   261
			{			
hgs
parents:
diff changeset
   262
            CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): aMessage->ThisPage () == 1");
hgs
parents:
diff changeset
   263
hgs
parents:
diff changeset
   264
			// 2. (False)
hgs
parents:
diff changeset
   265
			// add this page as the first node in chain pointed by 
hgs
parents:
diff changeset
   266
			// iRootNodeIterator. Delete any pages contained in the chain
hgs
parents:
diff changeset
   267
			// occuping this location first.
hgs
parents:
diff changeset
   268
			array = iRootNodeArray->At( iRootNodeIterator );
hgs
parents:
diff changeset
   269
			DeleteChainL( *array );
hgs
parents:
diff changeset
   270
			array->InsertL( 0, aMessage );
hgs
parents:
diff changeset
   271
			CleanupStack::Pop(); // aMessage, ownership transferred to msg chain.
hgs
parents:
diff changeset
   272
			iRootNodeIterator++;
hgs
parents:
diff changeset
   273
			// Return to the first message, if passed the
hgs
parents:
diff changeset
   274
			// maximum messages.
hgs
parents:
diff changeset
   275
			iRootNodeIterator %= KMaxCollectorMessages;
hgs
parents:
diff changeset
   276
hgs
parents:
diff changeset
   277
			if ( aMessageType == ECbsMessageLivecast )
hgs
parents:
diff changeset
   278
				{				
hgs
parents:
diff changeset
   279
                CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): aMessageType == ECbsMessageLivecast");
hgs
parents:
diff changeset
   280
hgs
parents:
diff changeset
   281
				// start timeout timer for livecast message
hgs
parents:
diff changeset
   282
				TKeyArrayFix key(0, ECmpTUint16);
hgs
parents:
diff changeset
   283
				TInt index;
hgs
parents:
diff changeset
   284
				iRootNodeArray->Find( array, key, index);
hgs
parents:
diff changeset
   285
				iMessageCleanupTimerArray->At( index )->StartTimer();
hgs
parents:
diff changeset
   286
				
hgs
parents:
diff changeset
   287
                CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): Timer started.");
hgs
parents:
diff changeset
   288
				}
hgs
parents:
diff changeset
   289
			}
hgs
parents:
diff changeset
   290
		else
hgs
parents:
diff changeset
   291
			{			
hgs
parents:
diff changeset
   292
            CBSLOGSTRING("CBSSERVER: CCbsRecCollector::CollectL(): CleanupStack::Pop()");
hgs
parents:
diff changeset
   293
			CleanupStack::Pop();
hgs
parents:
diff changeset
   294
			}
hgs
parents:
diff changeset
   295
        }
hgs
parents:
diff changeset
   296
    // mergedMessage == NULL if msg not completed,
hgs
parents:
diff changeset
   297
    // otherwise return the complete message
hgs
parents:
diff changeset
   298
	CBSLOGSTRING("CBSSERVER: <<< CCbsRecCollector::CollectL(), returning mergedMessage.");
hgs
parents:
diff changeset
   299
hgs
parents:
diff changeset
   300
    return mergedMessage;
hgs
parents:
diff changeset
   301
    }
hgs
parents:
diff changeset
   302
hgs
parents:
diff changeset
   303
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   304
// CCbsRecCollector::DeleteChainL
hgs
parents:
diff changeset
   305
// Deletes all message pages contained in aArray.
hgs
parents:
diff changeset
   306
// (other items were commented in a header).
hgs
parents:
diff changeset
   307
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   308
//  
hgs
parents:
diff changeset
   309
void CCbsRecCollector::DeleteChainL( 
hgs
parents:
diff changeset
   310
    CMessageBuffer& aArray ) const
hgs
parents:
diff changeset
   311
    {
hgs
parents:
diff changeset
   312
    aArray.ResetAndDestroy();
hgs
parents:
diff changeset
   313
    }
hgs
parents:
diff changeset
   314
hgs
parents:
diff changeset
   315
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   316
// CCbsRecCollector::AllPagesPresent
hgs
parents:
diff changeset
   317
// Returns ETrue if all pages of the message of aArray are present.
hgs
parents:
diff changeset
   318
// Counts pages in message chain aArray and compares the result
hgs
parents:
diff changeset
   319
// against the total number of pages in the message.
hgs
parents:
diff changeset
   320
// (other items were commented in a header).
hgs
parents:
diff changeset
   321
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   322
// 
hgs
parents:
diff changeset
   323
TBool CCbsRecCollector::AllPagesPresent( 
hgs
parents:
diff changeset
   324
    const CMessageBuffer& aArray ) const
hgs
parents:
diff changeset
   325
    {
hgs
parents:
diff changeset
   326
    TBool result( ETrue );
hgs
parents:
diff changeset
   327
    if ( TUint( aArray.Count() ) < aArray.At( 0 )->TotalPages() )
hgs
parents:
diff changeset
   328
        {
hgs
parents:
diff changeset
   329
        result = EFalse;        
hgs
parents:
diff changeset
   330
        }
hgs
parents:
diff changeset
   331
    
hgs
parents:
diff changeset
   332
    return result;
hgs
parents:
diff changeset
   333
    }
hgs
parents:
diff changeset
   334
hgs
parents:
diff changeset
   335
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   336
// CCbsRecCollector::MergePagesLC
hgs
parents:
diff changeset
   337
// Returns a complete message in aMessage.
hgs
parents:
diff changeset
   338
// Merges all pages in message chain aArray and returns
hgs
parents:
diff changeset
   339
// a pointer to the resulting assembled message. The pointer
hgs
parents:
diff changeset
   340
// is also left on the cleanup stack.
hgs
parents:
diff changeset
   341
// (other items were commented in a header).
hgs
parents:
diff changeset
   342
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   343
//
hgs
parents:
diff changeset
   344
CCbsMessage* CCbsRecCollector::MergePagesLC( 
hgs
parents:
diff changeset
   345
    CMessageBuffer& aArray ) const
hgs
parents:
diff changeset
   346
    {
hgs
parents:
diff changeset
   347
    if ( aArray.Count() <= 0 )
hgs
parents:
diff changeset
   348
        {
hgs
parents:
diff changeset
   349
        User::Leave( KErrNotFound );
hgs
parents:
diff changeset
   350
        }
hgs
parents:
diff changeset
   351
    // Create a new message based on first message page in the chain.
hgs
parents:
diff changeset
   352
    CCbsMessage* message = iFactory.CreateMessageL( *aArray.At( 0 ) );
hgs
parents:
diff changeset
   353
hgs
parents:
diff changeset
   354
    CleanupStack::PushL( message ); // left on cleanup stack
hgs
parents:
diff changeset
   355
hgs
parents:
diff changeset
   356
    // Traverse through the chain and merge contents.
hgs
parents:
diff changeset
   357
    TInt length( 0 );
hgs
parents:
diff changeset
   358
    TInt count( aArray.Count() );
hgs
parents:
diff changeset
   359
hgs
parents:
diff changeset
   360
    // If this is a Livecast message, use the 8-bit representation
hgs
parents:
diff changeset
   361
    // (message not decoded).
hgs
parents:
diff changeset
   362
    if ( message->IsLivecastMessage() )
hgs
parents:
diff changeset
   363
        {
hgs
parents:
diff changeset
   364
        for ( TInt j( 0 ); j < count; j++ )
hgs
parents:
diff changeset
   365
            {
hgs
parents:
diff changeset
   366
            length += aArray.At( j )->Contents8().Length();
hgs
parents:
diff changeset
   367
            }
hgs
parents:
diff changeset
   368
        
hgs
parents:
diff changeset
   369
        __ASSERT_DEBUG( length >= 0, CbsServerPanic( ECbsCollectorMergeFailed ) );
hgs
parents:
diff changeset
   370
hgs
parents:
diff changeset
   371
        message->ReserveContentSize8L( length );
hgs
parents:
diff changeset
   372
        count = aArray.Count();
hgs
parents:
diff changeset
   373
        
hgs
parents:
diff changeset
   374
        for ( TInt i( 1 ); i < count; i++ ) 
hgs
parents:
diff changeset
   375
            {
hgs
parents:
diff changeset
   376
            message->AppendContent8( aArray.At( i )->Contents8() );
hgs
parents:
diff changeset
   377
            }
hgs
parents:
diff changeset
   378
        }
hgs
parents:
diff changeset
   379
    // Else use the 16-bit representation (message already decoded)
hgs
parents:
diff changeset
   380
    else
hgs
parents:
diff changeset
   381
        {
hgs
parents:
diff changeset
   382
        for ( TInt j( 0 ); j < count; j++ )
hgs
parents:
diff changeset
   383
            {
hgs
parents:
diff changeset
   384
            length += aArray.At( j )->Contents().Length();
hgs
parents:
diff changeset
   385
            }
hgs
parents:
diff changeset
   386
    
hgs
parents:
diff changeset
   387
	    __ASSERT_DEBUG( length >= 0, CbsServerPanic( ECbsCollectorMergeFailed ) );
hgs
parents:
diff changeset
   388
hgs
parents:
diff changeset
   389
	    message->ReserveContentSizeL( length );
hgs
parents:
diff changeset
   390
	    count = aArray.Count();
hgs
parents:
diff changeset
   391
hgs
parents:
diff changeset
   392
    // Append the rest of the pages (first page handled earlier)
hgs
parents:
diff changeset
   393
	    for ( TInt i( 1 ); i < count; i++ ) 
hgs
parents:
diff changeset
   394
	        {
hgs
parents:
diff changeset
   395
	        message->AppendContent( aArray.At( i )->Contents() );
hgs
parents:
diff changeset
   396
	        }
hgs
parents:
diff changeset
   397
        }
hgs
parents:
diff changeset
   398
    return message;
hgs
parents:
diff changeset
   399
    }
hgs
parents:
diff changeset
   400
hgs
parents:
diff changeset
   401
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   402
// CCbsRecCollector::FindChainContainingPage
hgs
parents:
diff changeset
   403
// Returns the buffer containing pages of same message.
hgs
parents:
diff changeset
   404
// Finds and returns a message chain which already contains pages
hgs
parents:
diff changeset
   405
// of aMessage's message. If none is found, NULL is returned.
hgs
parents:
diff changeset
   406
// (other items were commented in a header).
hgs
parents:
diff changeset
   407
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   408
//
hgs
parents:
diff changeset
   409
CMessageBuffer* CCbsRecCollector::FindChainContainingPage( 
hgs
parents:
diff changeset
   410
    const CCbsMessage& aMessage ) const
hgs
parents:
diff changeset
   411
    {
hgs
parents:
diff changeset
   412
    TBool quitSeek( EFalse );
hgs
parents:
diff changeset
   413
    TInt seekIterator( 0 );
hgs
parents:
diff changeset
   414
    TCbsDbMessageKey key( aMessage.Key() );
hgs
parents:
diff changeset
   415
    TCbsDbTopicNumber topicNumber( aMessage.TopicNumber() );
hgs
parents:
diff changeset
   416
    CMessageBuffer* array = NULL;
hgs
parents:
diff changeset
   417
    
hgs
parents:
diff changeset
   418
    // find out if the root array contains pages of this message
hgs
parents:
diff changeset
   419
    while ( ( seekIterator < KMaxCollectorMessages ) && !quitSeek  )
hgs
parents:
diff changeset
   420
        {
hgs
parents:
diff changeset
   421
        array = iRootNodeArray->At( seekIterator );
hgs
parents:
diff changeset
   422
        if ( array->Count() > 0 ) 
hgs
parents:
diff changeset
   423
            {
hgs
parents:
diff changeset
   424
            CCbsMessage* msg = array->At( 0 );
hgs
parents:
diff changeset
   425
            if ( key == msg->Key() && topicNumber == msg->TopicNumber() )
hgs
parents:
diff changeset
   426
                {
hgs
parents:
diff changeset
   427
                quitSeek = ETrue;
hgs
parents:
diff changeset
   428
                }
hgs
parents:
diff changeset
   429
            }
hgs
parents:
diff changeset
   430
        seekIterator++;
hgs
parents:
diff changeset
   431
        }
hgs
parents:
diff changeset
   432
hgs
parents:
diff changeset
   433
    if ( !quitSeek )
hgs
parents:
diff changeset
   434
        {
hgs
parents:
diff changeset
   435
        array = NULL;
hgs
parents:
diff changeset
   436
        }
hgs
parents:
diff changeset
   437
    
hgs
parents:
diff changeset
   438
    return array;
hgs
parents:
diff changeset
   439
    }
hgs
parents:
diff changeset
   440
hgs
parents:
diff changeset
   441
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   442
// CCbsRecCollector::AddMessageToChainL
hgs
parents:
diff changeset
   443
// Adds message page aMessage to the correct position in message chain aArray
hgs
parents:
diff changeset
   444
//        
hgs
parents:
diff changeset
   445
// Message chains are ordered in ascending page number order.
hgs
parents:
diff changeset
   446
// Duplicate pages are not accepted.
hgs
parents:
diff changeset
   447
//
hgs
parents:
diff changeset
   448
// Ownership of aMessage is transferred to aArray, if the given page
hgs
parents:
diff changeset
   449
// hasn't been already collected. The given page will be deleted,
hgs
parents:
diff changeset
   450
// if it already exists in the chain.
hgs
parents:
diff changeset
   451
// (other items were commented in a header).
hgs
parents:
diff changeset
   452
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   453
//
hgs
parents:
diff changeset
   454
void CCbsRecCollector::AddMessageToChainL( 
hgs
parents:
diff changeset
   455
    CCbsMessage* aMessage, 
hgs
parents:
diff changeset
   456
    CMessageBuffer& aArray ) const
hgs
parents:
diff changeset
   457
    {
hgs
parents:
diff changeset
   458
    // Find out a position for this page in the chain.
hgs
parents:
diff changeset
   459
    TInt chainLength( aArray.Count() );    
hgs
parents:
diff changeset
   460
    TInt insertPosition( -1 );
hgs
parents:
diff changeset
   461
    TBool duplicate( EFalse );
hgs
parents:
diff changeset
   462
hgs
parents:
diff changeset
   463
    for ( TInt i( 0 ); ( i < chainLength ) && !duplicate; i++ )
hgs
parents:
diff changeset
   464
        {
hgs
parents:
diff changeset
   465
        CCbsMessage* msg = aArray.At( i );
hgs
parents:
diff changeset
   466
        if ( insertPosition == -1 && msg->ThisPage() > aMessage->ThisPage() )
hgs
parents:
diff changeset
   467
            {
hgs
parents:
diff changeset
   468
            insertPosition = i;
hgs
parents:
diff changeset
   469
            }
hgs
parents:
diff changeset
   470
        else if ( msg->ThisPage() == aMessage->ThisPage() )
hgs
parents:
diff changeset
   471
            {
hgs
parents:
diff changeset
   472
            duplicate = ETrue; // This page has been already collected
hgs
parents:
diff changeset
   473
            delete aMessage;
hgs
parents:
diff changeset
   474
            }
hgs
parents:
diff changeset
   475
        }
hgs
parents:
diff changeset
   476
hgs
parents:
diff changeset
   477
    // If this message was not a duplicate, add it to the chain
hgs
parents:
diff changeset
   478
    if ( !duplicate )
hgs
parents:
diff changeset
   479
        {
hgs
parents:
diff changeset
   480
        if ( insertPosition == -1 )
hgs
parents:
diff changeset
   481
            {
hgs
parents:
diff changeset
   482
            aArray.AppendL( aMessage );
hgs
parents:
diff changeset
   483
            }
hgs
parents:
diff changeset
   484
        else
hgs
parents:
diff changeset
   485
            {
hgs
parents:
diff changeset
   486
            aArray.InsertL( insertPosition, aMessage );
hgs
parents:
diff changeset
   487
            }
hgs
parents:
diff changeset
   488
        }    
hgs
parents:
diff changeset
   489
    }
hgs
parents:
diff changeset
   490
hgs
parents:
diff changeset
   491
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   492
// CCbsRecCollector::CheckPageAreaInfoMatch
hgs
parents:
diff changeset
   493
// Checks if these pages can be merged. Returns ETrue, if merging is acceptable.
hgs
parents:
diff changeset
   494
//   
hgs
parents:
diff changeset
   495
// Decision is based network information and geographical scope of 
hgs
parents:
diff changeset
   496
// pages. Network information consists of cell id, location area code
hgs
parents:
diff changeset
   497
// and operator id.
hgs
parents:
diff changeset
   498
// 
hgs
parents:
diff changeset
   499
// Assumption: aPage1 and aPage have identical message
hgs
parents:
diff changeset
   500
// identifiers and serial numbers. 
hgs
parents:
diff changeset
   501
// Returns ETrue if the pages are of same message.
hgs
parents:
diff changeset
   502
// On EFalse previous pages should be deleted.
hgs
parents:
diff changeset
   503
// (other items were commented in a header).
hgs
parents:
diff changeset
   504
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   505
//
hgs
parents:
diff changeset
   506
TBool CCbsRecCollector::CheckPageAreaInfoMatch( 
hgs
parents:
diff changeset
   507
    const CCbsMessage& aPage1, 
hgs
parents:
diff changeset
   508
    const CCbsMessage& aPage2 ) const
hgs
parents:
diff changeset
   509
    {   
hgs
parents:
diff changeset
   510
    RMobilePhone::TMobilePhoneNetworkInfoV1 info1;
hgs
parents:
diff changeset
   511
    RMobilePhone::TMobilePhoneNetworkInfoV1 info2;
hgs
parents:
diff changeset
   512
hgs
parents:
diff changeset
   513
    aPage1.GetPLMN( info1 );
hgs
parents:
diff changeset
   514
    aPage2.GetPLMN( info2 );
hgs
parents:
diff changeset
   515
hgs
parents:
diff changeset
   516
    TBool result( EFalse );
hgs
parents:
diff changeset
   517
hgs
parents:
diff changeset
   518
    if ( info1.iCountryCode == KRecMessageNoNetworkInfo || 
hgs
parents:
diff changeset
   519
        info2.iCountryCode == KRecMessageNoNetworkInfo )
hgs
parents:
diff changeset
   520
        {
hgs
parents:
diff changeset
   521
        // Network info is unavailable; we must assume that the aPage1
hgs
parents:
diff changeset
   522
        // is of the same page area as aPage2, so we return ETrue
hgs
parents:
diff changeset
   523
        // unconditionally.
hgs
parents:
diff changeset
   524
        result = ETrue;
hgs
parents:
diff changeset
   525
        }
hgs
parents:
diff changeset
   526
hgs
parents:
diff changeset
   527
    if ( info1.iCountryCode == info2.iCountryCode && 
hgs
parents:
diff changeset
   528
        info1.iNetworkId == info2.iNetworkId )
hgs
parents:
diff changeset
   529
        // PLMN match
hgs
parents:
diff changeset
   530
        {
hgs
parents:
diff changeset
   531
        if ( aPage1.LAC() == aPage2.LAC() )
hgs
parents:
diff changeset
   532
            // LAC match
hgs
parents:
diff changeset
   533
            {
hgs
parents:
diff changeset
   534
            if ( aPage1.CellId() == aPage2.CellId() )
hgs
parents:
diff changeset
   535
                // Cell match
hgs
parents:
diff changeset
   536
                {
hgs
parents:
diff changeset
   537
                // Full network information match
hgs
parents:
diff changeset
   538
                result = ETrue;
hgs
parents:
diff changeset
   539
                }
hgs
parents:
diff changeset
   540
            else
hgs
parents:
diff changeset
   541
                {
hgs
parents:
diff changeset
   542
                // Cell mismatch
hgs
parents:
diff changeset
   543
                if ( aPage1.GeographicalScope() == 
hgs
parents:
diff changeset
   544
                    ECbsRecGeographicalScopeCell )
hgs
parents:
diff changeset
   545
                    // Cell id mismatch and scoped cell wide.
hgs
parents:
diff changeset
   546
                    {
hgs
parents:
diff changeset
   547
                    result = EFalse;
hgs
parents:
diff changeset
   548
                    }
hgs
parents:
diff changeset
   549
                else
hgs
parents:
diff changeset
   550
                    // Cell id mismatch, not scoped cell wide.
hgs
parents:
diff changeset
   551
                    {
hgs
parents:
diff changeset
   552
                    result = ETrue;
hgs
parents:
diff changeset
   553
                    }
hgs
parents:
diff changeset
   554
                }
hgs
parents:
diff changeset
   555
            }            
hgs
parents:
diff changeset
   556
        else
hgs
parents:
diff changeset
   557
            // LAC mismatch
hgs
parents:
diff changeset
   558
            {
hgs
parents:
diff changeset
   559
            if ( aPage1.GeographicalScope() == 
hgs
parents:
diff changeset
   560
                ECbsRecGeographicalScopePLMN )
hgs
parents:
diff changeset
   561
                {
hgs
parents:
diff changeset
   562
                // LAC mismatch but scoped operator-wide
hgs
parents:
diff changeset
   563
                result = ETrue;
hgs
parents:
diff changeset
   564
                }
hgs
parents:
diff changeset
   565
            else
hgs
parents:
diff changeset
   566
                {
hgs
parents:
diff changeset
   567
                // LAC mismatch and not scoped operator-wide
hgs
parents:
diff changeset
   568
                result = EFalse;
hgs
parents:
diff changeset
   569
                }
hgs
parents:
diff changeset
   570
            }
hgs
parents:
diff changeset
   571
        }
hgs
parents:
diff changeset
   572
    else
hgs
parents:
diff changeset
   573
        // PLMN mismatch
hgs
parents:
diff changeset
   574
        {
hgs
parents:
diff changeset
   575
        result = EFalse; // operator mismatch
hgs
parents:
diff changeset
   576
        }
hgs
parents:
diff changeset
   577
hgs
parents:
diff changeset
   578
    return result;    
hgs
parents:
diff changeset
   579
    }
hgs
parents:
diff changeset
   580
hgs
parents:
diff changeset
   581
hgs
parents:
diff changeset
   582
// ================= OTHER EXPORTED FUNCTIONS ==============
hgs
parents:
diff changeset
   583
hgs
parents:
diff changeset
   584
//  End of File