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