os/kernelhwsrv/kernel/eka/debug/crashMonitor/src/scmconfig.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32\debug\crashMonitor\src\scmconfig.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
/**
sl@0
    19
 @file
sl@0
    20
 @internalTechnology
sl@0
    21
*/
sl@0
    22
sl@0
    23
#include <e32err.h>
sl@0
    24
#include <e32const.h>
sl@0
    25
#include <e32const_private.h>
sl@0
    26
sl@0
    27
#include <scmconfig.h>
sl@0
    28
#include <scmconfigitem.h>
sl@0
    29
#include <scmdatatypes.h>
sl@0
    30
sl@0
    31
namespace Debug
sl@0
    32
	{
sl@0
    33
	/**
sl@0
    34
	 * SCMConfiguration constructor
sl@0
    35
	 * Initialises the configuration object to default values
sl@0
    36
	 */
sl@0
    37
	SCMConfiguration::SCMConfiguration() 
sl@0
    38
	: iConfigList(NULL)
sl@0
    39
		{
sl@0
    40
		}
sl@0
    41
	
sl@0
    42
	/**
sl@0
    43
	 * SCMConfiguration destructor
sl@0
    44
	 */
sl@0
    45
	SCMConfiguration::~SCMConfiguration()
sl@0
    46
		{	
sl@0
    47
		ClearList();	
sl@0
    48
		}
sl@0
    49
sl@0
    50
	/**
sl@0
    51
	 * Goes to the flash and reads the configuration block and populates the object state
sl@0
    52
	 * accordingly
sl@0
    53
	 * @return one of the system wide error codes
sl@0
    54
	 */
sl@0
    55
	TInt SCMConfiguration::Deserialize(TByteStreamReader& aReader)
sl@0
    56
		{		
sl@0
    57
		if( !iConfigList)
sl@0
    58
			{
sl@0
    59
			// we need to set up a default configuration to load the data into
sl@0
    60
			TInt err = SetDefaultConfig();
sl@0
    61
			if(err != KErrNone)
sl@0
    62
				{
sl@0
    63
				CLTRACE1("SCMConfiguration::Deserialize SetDefaultConfig failed err = %d", err);
sl@0
    64
				return err;
sl@0
    65
				}
sl@0
    66
			}
sl@0
    67
		
sl@0
    68
		TInt startPos = aReader.CurrentPosition();		
sl@0
    69
		
sl@0
    70
		TBuf8<10> magicNumbers;
sl@0
    71
		// try and read the magic numbers - if they dont exist then 
sl@0
    72
		// there is not an scm config there
sl@0
    73
		const TInt KLen = KScmConfigHeaderString().Length();
sl@0
    74
		for(TInt i=0;i<KLen;i++)
sl@0
    75
			{
sl@0
    76
			TUint8 b = aReader.ReadByte();			
sl@0
    77
			magicNumbers.Append(TChar(b));	
sl@0
    78
			}
sl@0
    79
		
sl@0
    80
		if(magicNumbers.Compare(KScmConfigHeaderString()) != 0)
sl@0
    81
			{
sl@0
    82
			CLTRACE("No scm, config to read !");
sl@0
    83
			return KErrNotReady;
sl@0
    84
			}
sl@0
    85
				
sl@0
    86
		TConfigItem* item = iConfigList;
sl@0
    87
		while(item)
sl@0
    88
			{
sl@0
    89
			item->Deserialize(aReader);
sl@0
    90
			item = item->iNext;
sl@0
    91
			}
sl@0
    92
		
sl@0
    93
		TInt endPos = aReader.CurrentPosition();
sl@0
    94
		if( endPos - startPos != GetSize())
sl@0
    95
			{
sl@0
    96
			// error between actual size & real size in data
sl@0
    97
			CLTRACE("SCMConfiguration::Deserialize size error");	
sl@0
    98
			return KErrCorrupt;
sl@0
    99
			}			
sl@0
   100
		return KErrNone;			
sl@0
   101
		}
sl@0
   102
	
sl@0
   103
	/**
sl@0
   104
	 * This writes the current configuration object state to flash. This configuration will be used on the next crash
sl@0
   105
	 * @return one of the system wide error codes
sl@0
   106
	 */
sl@0
   107
	TInt SCMConfiguration::Serialize(TByteStreamWriter& aWriter)	
sl@0
   108
		{		
sl@0
   109
		if( !iConfigList)
sl@0
   110
			{
sl@0
   111
			CLTRACE("SCMConfiguration::Serialize ERROR - NO LIST!!");
sl@0
   112
			return KErrNotReady;
sl@0
   113
			}
sl@0
   114
		
sl@0
   115
		TInt startPos = aWriter.CurrentPosition();
sl@0
   116
		
sl@0
   117
		// write the number of crashes and magic numbers
sl@0
   118
		
sl@0
   119
		// try and read the magic numbers - if they dont exist then 
sl@0
   120
		// there is not an scm config there
sl@0
   121
		const TInt KLen = KScmConfigHeaderString().Length();
sl@0
   122
		const TDesC8& des = KScmConfigHeaderString();
sl@0
   123
		for(TInt i=0;i<KLen;i++)
sl@0
   124
			{
sl@0
   125
			aWriter.WriteByte(des[i]);
sl@0
   126
			}				
sl@0
   127
		
sl@0
   128
		TConfigItem* item = iConfigList;
sl@0
   129
		while(item)
sl@0
   130
			{
sl@0
   131
			item->Serialize(aWriter);
sl@0
   132
			item = item->iNext;
sl@0
   133
			}
sl@0
   134
sl@0
   135
		TInt endPos = aWriter.CurrentPosition();
sl@0
   136
		if( endPos - startPos != GetSize())
sl@0
   137
			{
sl@0
   138
			// error between actual size & real size in data
sl@0
   139
			CLTRACE("SCMConfiguration::Serialize size error");	
sl@0
   140
			return KErrCorrupt;
sl@0
   141
			}						
sl@0
   142
		return KErrNone;
sl@0
   143
		}
sl@0
   144
	
sl@0
   145
	/**
sl@0
   146
	 * Returns entire size of the SCMConfiguration block
sl@0
   147
	 * @return Size
sl@0
   148
	 */
sl@0
   149
	TInt SCMConfiguration::GetSize() const
sl@0
   150
		{
sl@0
   151
		// returns the size of all the config items when serialized to disk / flash
sl@0
   152
		return (TConfigItem::ELast * iConfigList->GetSize()) + KScmConfigHeaderString().Length();
sl@0
   153
		}
sl@0
   154
	
sl@0
   155
	/** 
sl@0
   156
	 * This will return, one at a time, the highest priority. 
sl@0
   157
	 * @see ResetToHighestPriority()
sl@0
   158
	 * @param aSizeToDump this will contain the size in bytes of data to dump for this type - 0 means dump all
sl@0
   159
	 * @return Data type to dump 
sl@0
   160
	 */
sl@0
   161
	TConfigItem* SCMConfiguration::GetNextItem()
sl@0
   162
		{
sl@0
   163
		if(!iNextItem)
sl@0
   164
			{
sl@0
   165
			return NULL;
sl@0
   166
			}
sl@0
   167
			
sl@0
   168
		//get the values we need
sl@0
   169
		TConfigItem* item  = iNextItem;	
sl@0
   170
		
sl@0
   171
		//Now move iNextItem to be next in the list
sl@0
   172
		iNextItem = iNextItem->iNext;			
sl@0
   173
		return item;
sl@0
   174
		}	
sl@0
   175
	
sl@0
   176
	/**
sl@0
   177
	 * Deletes the linked list
sl@0
   178
	 * @return system wide OS code
sl@0
   179
	 */
sl@0
   180
	void SCMConfiguration::ClearList()
sl@0
   181
		{
sl@0
   182
		if(!iConfigList)
sl@0
   183
			{
sl@0
   184
			return;
sl@0
   185
			}
sl@0
   186
		
sl@0
   187
		//all we need to do in here is delete the members of our linked list
sl@0
   188
		TConfigItem* item = iConfigList;
sl@0
   189
		
sl@0
   190
		do{			
sl@0
   191
			TConfigItem* tmp = item->iNext;
sl@0
   192
			delete item;		
sl@0
   193
			item = tmp;		
sl@0
   194
		}
sl@0
   195
		while(item != NULL);
sl@0
   196
		
sl@0
   197
		iConfigList = NULL;
sl@0
   198
		}
sl@0
   199
	
sl@0
   200
	/**
sl@0
   201
	 * Rather than reading the configuration from the flash, this method sets up the configuration object
sl@0
   202
	 * to a default configuration type
sl@0
   203
	 * @return one of the system wide error codes
sl@0
   204
	 */ 
sl@0
   205
	TInt SCMConfiguration::SetDefaultConfig()
sl@0
   206
		{
sl@0
   207
		//flush the object first
sl@0
   208
		ClearList();
sl@0
   209
	
sl@0
   210
		//This is a predefined default config - in the future we may have multiple defaults based on use case
sl@0
   211
		// currently however we use a fixed size list of config items of size TConfigItem::ELast		
sl@0
   212
		// also the TSCMDataType of each item must be unique				
sl@0
   213
		
sl@0
   214
		for(TInt cnt = TConfigItem::ELast - 1; cnt >= 0; cnt --)
sl@0
   215
			{			
sl@0
   216
			TInt priority = cnt + 1; 
sl@0
   217
			
sl@0
   218
			//Lets not do these by default
sl@0
   219
			if((TConfigItem::TSCMDataType)cnt == TConfigItem::EThreadsUsrStack || (TConfigItem::TSCMDataType)cnt == TConfigItem::EThreadsSvrStack)
sl@0
   220
				{
sl@0
   221
				priority = 0;
sl@0
   222
				}
sl@0
   223
			
sl@0
   224
			//set it with the priority of its enum (ie. assume that the enum is listed in its priority - it is)
sl@0
   225
			//by default dump everything until we run out of space
sl@0
   226
			TInt err = CreateConfigItem((TConfigItem::TSCMDataType)cnt, priority, 0);
sl@0
   227
			if(KErrNone != err)
sl@0
   228
				{
sl@0
   229
				return err;
sl@0
   230
				}
sl@0
   231
			}
sl@0
   232
		
sl@0
   233
		return KErrNone;		
sl@0
   234
		}
sl@0
   235
		
sl@0
   236
	/**
sl@0
   237
	 * This configures the required data for a given configuration item
sl@0
   238
	 * Note that aSizeToDump is only used in the case of memory dumps such as stacks
sl@0
   239
	 * @param aDataType - Type of data to dump
sl@0
   240
	 * @param aPriority - its priority 0-256. 0 Means do not dump and 256 is highest priority
sl@0
   241
	 * @param aSizeToDump - amount in bytes to dump. Only relevant for memory dumps and ignored when aPriority is 0
sl@0
   242
	 * @return one of the OS wide return codes
sl@0
   243
	 */
sl@0
   244
	TInt SCMConfiguration::CreateConfigItem(const TConfigItem::TSCMDataType aDataType, const TUint8 aPriority, const TInt32 aSizeToDump)
sl@0
   245
		{
sl@0
   246
		//create the config item
sl@0
   247
		TConfigItem* item = new TConfigItem(aDataType, aPriority, aSizeToDump);
sl@0
   248
		
sl@0
   249
		//insert to priority list
sl@0
   250
		return InsertToList(item);		
sl@0
   251
		}
sl@0
   252
		
sl@0
   253
	
sl@0
   254
	/**
sl@0
   255
	 * ModifyConfigItemPriority - modifies prioity for a given configuration item
sl@0
   256
	 * @param aDataType - The unique type of the config item
sl@0
   257
	 * @param aPriority - its priority 0-256. 0 Means do not dump and 256 is highest priority
sl@0
   258
	 * @return one of the OS wide return codes
sl@0
   259
	 */
sl@0
   260
	TInt  SCMConfiguration::ModifyConfigItemPriority(const TConfigItem::TSCMDataType aDataType, const TUint8 aPriority)
sl@0
   261
		{
sl@0
   262
sl@0
   263
		// find the item with the matching data type
sl@0
   264
		TConfigItem* item = iConfigList;		
sl@0
   265
		while(item)
sl@0
   266
			{
sl@0
   267
			if(item->iDataType == aDataType)
sl@0
   268
				{
sl@0
   269
				break;
sl@0
   270
				}
sl@0
   271
			item = item->iNext;			
sl@0
   272
			}
sl@0
   273
	
sl@0
   274
		if(!item)
sl@0
   275
			{
sl@0
   276
			return KErrNotFound;
sl@0
   277
			}
sl@0
   278
		
sl@0
   279
		item->iPriority = aPriority;
sl@0
   280
		
sl@0
   281
		// now reorder the list according to new priority
sl@0
   282
		TInt err = RemoveFromList(item);
sl@0
   283
		if(err != KErrNone)
sl@0
   284
			{
sl@0
   285
			return err;
sl@0
   286
			}
sl@0
   287
		
sl@0
   288
		err = InsertToList(item);
sl@0
   289
sl@0
   290
		if(err != KErrNone)
sl@0
   291
			{
sl@0
   292
			return err;
sl@0
   293
			}
sl@0
   294
		
sl@0
   295
		return KErrNone;
sl@0
   296
		}
sl@0
   297
sl@0
   298
/**
sl@0
   299
 * Removes item from the linked list
sl@0
   300
 * @param aItem - item to remove
sl@0
   301
 * @return OS code
sl@0
   302
 */
sl@0
   303
TInt SCMConfiguration::RemoveFromList(TConfigItem* aItem)
sl@0
   304
		{
sl@0
   305
		if(!aItem)
sl@0
   306
			{
sl@0
   307
			return KErrArgument;
sl@0
   308
			}
sl@0
   309
		
sl@0
   310
		if(!iConfigList)
sl@0
   311
			{
sl@0
   312
			return KErrCorrupt;  // oops no list to remove
sl@0
   313
			}
sl@0
   314
		
sl@0
   315
		
sl@0
   316
		if(aItem == iConfigList)
sl@0
   317
			{
sl@0
   318
			// special case remove from beginning of list
sl@0
   319
			iConfigList = iConfigList->iNext;
sl@0
   320
			return KErrNone;
sl@0
   321
			}
sl@0
   322
		
sl@0
   323
		TConfigItem* item = iConfigList; 
sl@0
   324
		while(item)
sl@0
   325
			{
sl@0
   326
			// is the next item the match ?
sl@0
   327
			if(item->iNext == aItem)
sl@0
   328
				{
sl@0
   329
				item->iNext = aItem->iNext;
sl@0
   330
				return KErrNone;
sl@0
   331
				}		
sl@0
   332
			item = item->iNext;	
sl@0
   333
			}
sl@0
   334
		
sl@0
   335
		return KErrNotFound;	
sl@0
   336
		}
sl@0
   337
sl@0
   338
/**
sl@0
   339
 * Inserts a priority item into the linked list in its correct location
sl@0
   340
 * @param aItem - item to insert
sl@0
   341
 * @return OS code
sl@0
   342
 */
sl@0
   343
TInt SCMConfiguration::InsertToList(TConfigItem* aItem)
sl@0
   344
	{ 	
sl@0
   345
	
sl@0
   346
	//if the list is empty, then this is the only item
sl@0
   347
	if(!iConfigList)
sl@0
   348
		{
sl@0
   349
		iConfigList = aItem;			
sl@0
   350
		return KErrNone;
sl@0
   351
		}
sl@0
   352
	
sl@0
   353
	//should it go at the start? special case not covered by while loop
sl@0
   354
	TConfigItem* temp;
sl@0
   355
	
sl@0
   356
	if(aItem->iPriority >= iConfigList->iPriority)
sl@0
   357
		{
sl@0
   358
		temp = iConfigList;
sl@0
   359
		iConfigList = aItem;
sl@0
   360
		aItem->iNext = temp;
sl@0
   361
		return KErrNone;
sl@0
   362
		}
sl@0
   363
	
sl@0
   364
	TConfigItem* item = iConfigList;
sl@0
   365
	
sl@0
   366
	do{		
sl@0
   367
		//if we get to the end of the list and the item still hasnt been assigned then it must be lowest priority
sl@0
   368
		if(item->iNext == NULL)
sl@0
   369
			{
sl@0
   370
			item->iNext = aItem;
sl@0
   371
			return KErrNone;
sl@0
   372
			}
sl@0
   373
		
sl@0
   374
		//check if its priority is between these
sl@0
   375
		if(aItem->iPriority < item->iPriority && aItem->iPriority >= item->iNext->iPriority)
sl@0
   376
			{
sl@0
   377
			//insert between these nodes
sl@0
   378
			temp = item->iNext;
sl@0
   379
			item->iNext = aItem;
sl@0
   380
			aItem->iNext = temp;
sl@0
   381
			return KErrNone;
sl@0
   382
			}
sl@0
   383
	
sl@0
   384
		item = item->iNext;	
sl@0
   385
	}
sl@0
   386
	while(item != NULL);	
sl@0
   387
	
sl@0
   388
	//should never get here
sl@0
   389
	return KErrUnknown;
sl@0
   390
	}
sl@0
   391
	
sl@0
   392
/**
sl@0
   393
 * This resets the next item counter back to the highest priority item in the list
sl@0
   394
 */
sl@0
   395
void SCMConfiguration::ResetToHighestPriority()
sl@0
   396
	{
sl@0
   397
	//set the next item counter back to the head of the list
sl@0
   398
	iNextItem = iConfigList;
sl@0
   399
	}
sl@0
   400
sl@0
   401
/**
sl@0
   402
 * Overloaded == operator
sl@0
   403
 * @param aOther Item to compare
sl@0
   404
 * @return
sl@0
   405
 */
sl@0
   406
TBool SCMConfiguration::operator == (const SCMConfiguration& aOther) const
sl@0
   407
	{
sl@0
   408
	
sl@0
   409
	if(!iConfigList && !aOther.iConfigList)
sl@0
   410
		{
sl@0
   411
		return ETrue;
sl@0
   412
		}
sl@0
   413
	 		
sl@0
   414
	if((!iConfigList && aOther.iConfigList) || (iConfigList && !aOther.iConfigList))
sl@0
   415
		{
sl@0
   416
		return EFalse;
sl@0
   417
		}
sl@0
   418
	
sl@0
   419
	
sl@0
   420
	TConfigItem* item1 = iConfigList;
sl@0
   421
	TConfigItem* item2 = aOther.iConfigList;
sl@0
   422
	
sl@0
   423
	while(item1 && item2)
sl@0
   424
		{
sl@0
   425
		if(!(*item1 == *item2))
sl@0
   426
			{
sl@0
   427
			return EFalse;
sl@0
   428
			}
sl@0
   429
		
sl@0
   430
		item1 = item1->iNext;			
sl@0
   431
		item2 = item2->iNext;			
sl@0
   432
		}
sl@0
   433
sl@0
   434
	if( item1 != item2)  // both should now be null - if not then lists were different lengths
sl@0
   435
		{
sl@0
   436
		return EFalse;
sl@0
   437
		}
sl@0
   438
		
sl@0
   439
	return ETrue;
sl@0
   440
	
sl@0
   441
	}
sl@0
   442
 	
sl@0
   443
/**
sl@0
   444
 * Getter for the head of the SCMConfig list
sl@0
   445
 * @return Head of List
sl@0
   446
 */	
sl@0
   447
TConfigItem* SCMConfiguration::ConfigList() const
sl@0
   448
	{
sl@0
   449
	// returns the head of the list	
sl@0
   450
	return iConfigList;
sl@0
   451
	} 
sl@0
   452
} //End of debug namespace
sl@0
   453
sl@0
   454
//eof
sl@0
   455
sl@0
   456
sl@0
   457
sl@0
   458