diff -r a151135b0cf9 -r aa2539c91954 tracesrv/tracecore/btrace_handler/src/BTraceOstCategoryBitmap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tracesrv/tracecore/btrace_handler/src/BTraceOstCategoryBitmap.cpp Fri Oct 08 14:56:39 2010 +0300 @@ -0,0 +1,1446 @@ +// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Trace Core +// + +#include +#include + +#include "BTraceOstCategoryBitmap.h" +#include "TraceCoreOstHeader.h" +#include "TraceCoreCommon.h" +#include "TraceCore.h" +#include "TraceCoreNotifier.h" +#include "TraceCoreConstants.h" +#include "TraceCoreDebug.h" +#include "TraceCoreSettings.h" +#include "BTraceOstCategoryHandler.h" + +#include "OstTraceDefinitions.h" +#ifdef OST_TRACE_COMPILER_IN_USE +#include "BTraceOstCategoryBitmapTraces.h" +#endif + + +//Split: These needed from sos_mon_isi_m.h (which is removed): +#define SOS_MON_TRACECORE_OST_ACTIVATION_REQ 0xD4 + +// OST message type +#define SOS_MON_TRACECORE_OST_ACTIVATION 1 +#define SOS_MON_TRACECORE_OST_ACTIVATION_QUERY 2 + +/** + * OST activation message types + */ +#define SOS_MON_TRACECORE_OST_DEACTIVATE 0 +#define SOS_MON_TRACECORE_OST_ACTIVATE 1 +#define SOS_MON_TRACECORE_OST_DEACTIVATE_ALL 2 +#define SOS_MON_TRACECORE_OST_ACTIVATE_ALL 3 +#define SOS_MON_TRACECORE_OST_OVERWRITE 4 + + +/** + * Offset to OST message id + * Field length 1 byte + */ +const TInt KOstMessageIdOffset = 0; + +/** + * Offset to activation info + * Field length 1 byte + */ +const TInt KOstActivationInfoOffset = 3; + +/** + * Offset to Number of groups field + * Field length 4 bytes + */ +const TInt KOstNumberOfGroupsOffset = 4; + +/** + * Offset to Component id + * Field length 4 bytes + */ +const TInt KOstComponentIdOffset = 8; + +/** + * Offset to 1st Group Id + * Field length 2 bytes + */ +const TInt KOstGroupIdOffset = 12; + +/** + * Minimum OST frame length + * - Message ID (1 byte) + * - Fillers (2 bytes) + * - Activation info (1 byte) + * - Number of groups (4 bytes) + * - Component ID (4 bytes) + */ +const TInt KOstMinFrameLength = 12; + +/** + * Group id length, 16bits, 2 bytes + */ +const TUint KGroupIdLength = 2; + +/** + * Increase array size + */ +const TUint KOstComponentsArrayGranularity = 8; + +/** + * Maximum activation buffer length + */ +const TUint32 KMaxActivationBufferLength = 1024 * 16; + +/** + * Constants for bit manipulation + */ +const TInt K8BitShift = 8; +const TInt K16BitShift = 16; +const TInt K24BitShift = 24; +const TInt K8BitMask = 0xff; +const TInt K4Bytes = 4; +const TInt K2Bytes = 2; + +/** + * Number of bytes to shift the group ID + */ +#define GRP_SHIFT 16 + +/** + * Number of bytes to shift the group ID + */ +#define GRP_MASK 0x00ff0000 + +/** + * Dummy handler used when no traces activated + */ +TBool DummyBTraceHandler(TUint32,TUint32,const TUint32,const TUint32,const TUint32,const TUint32,const TUint32,const TUint32) + { + return EFalse; + } + +BTrace::THandler oldHandler; + +/** + * Reads 16 bits from buffer + */ +TUint32 Read16(const TUint8* aPtr) + { + return ( (TUint32 )*aPtr ) | ( ( (TUint32 )*(aPtr + 1 ) ) << K8BitShift ); // CodForChk_Dis_Magic + } + +/** + * Reads 32 bits from buffer + */ +TUint32 Read32(const TUint8* aPtr) + { + return ( (TUint32 )*aPtr ) | + ( ( (TUint32 )*(aPtr + 1 ) ) << K8BitShift ) | // CodForChk_Dis_Magic + ( ( (TUint32 )*(aPtr + 2 ) ) << K16BitShift ) | // CodForChk_Dis_Magic + ( ( (TUint32 )*(aPtr + 3 ) ) << K24BitShift ); // CodForChk_Dis_Magic + } + +/** + * Endian swapper for 32-bit variable + */ +#define SWAP32( num ) ( \ + ( ( ( num ) & 0xff000000 ) >> K24BitShift ) | ( ( ( num ) & 0x00ff0000 ) >> K8BitShift ) | \ + ( ( ( num ) & 0x0000ff00 ) << K8BitShift ) | ( ( ( num ) & 0x000000ff ) << K24BitShift ) ) + +/** + * Endian swapper for 16-bit variable + */ +#define SWAP16( num ) ( ( ( ( num ) & 0xff00 ) >> K8BitShift ) | ( ( ( num ) & 0x00ff ) << K8BitShift ) ) + +/** + * Constructor + */ +DBTraceOstCategoryBitmap::DBTraceOstCategoryBitmap(DBTraceOstCategoryHandler* aBTraceOstCategoryHandler) : + iOstComponents(NULL), + iTmpArray(NULL), + iChangedArray(NULL), + iActivationBuffer(NULL), + iBTraceOstCategoryHandler( aBTraceOstCategoryHandler ) + { + } + +/** + * Destructor + */ +DBTraceOstCategoryBitmap::~DBTraceOstCategoryBitmap() + { + Kern::Free( iActivationBuffer ); + iActivationBuffer = NULL; + + CleanupComponentsArrays(); + } + +/** + * Init TraceBitmap + */ +TInt DBTraceOstCategoryBitmap::Init() + { + iOstComponents = new RArray(KOstComponentsArrayGranularity); + if(!iOstComponents) + return KErrNoMemory; + iTmpArray = new RArray(KOstComponentsArrayGranularity); + if(!iTmpArray) + { + CleanupComponentsArrays(); + return KErrNoMemory; + } + iChangedArray = new RArray(1); + if(!iChangedArray) + { + CleanupComponentsArrays(); + return KErrNoMemory; + } + + AllocateActivationBuffer(); + + // Init bitmap + TInt err = DTraceCoreActivationBase::Init( SOS_MON_TRACECORE_OST_ACTIVATION_REQ); + if (err == KErrNone) + { + // Subscribe message + err = DTraceCoreActivationBase::SubscribeMessage(OstConstants::OstBaseProtocol::KOstTraceActivationProtocol, + EMessageHeaderFormatOst); + + // Save old BTrace handler and use dummy for better performance + oldHandler = BTrace::SetHandler(DummyBTraceHandler); + } + + return err; + } + +/** + * Activate trace group + * + * @param aComponentId The component ID + * @param aGroupId The group ID + */ +void DBTraceOstCategoryBitmap::ActivateTrace(const TUint32 aComponentId, const TUint32 aGroupId) + { + OstTraceExt2( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_ACTIVATETRACE_ENTRY,"> DBTraceOstCategoryBitmap::ActivateTrace CID:0x%x GID:0x%x", aComponentId, aGroupId ); + //TODO: check is thread context (assert) + //TODO: can be executed only from iActivationQ (__ASSERT_DEBUG) + + if (GroupIdIsValid(aGroupId)) + { + //TODO: check how many users use this array (use atomics to increment/decrement) + CopyArray(iOstComponents, iTmpArray); + CleanupComponentsArray(*iChangedArray); + + TInt index = AddComponentId(aComponentId, *iTmpArray); + AddGroupId(aComponentId, aGroupId, index, *iTmpArray, *iChangedArray); + SetNewComponentsArrayPtr( iTmpArray ); + + //notify internal listeners and update internal activation cache + HandleTraceActivationChanges(*iChangedArray); + NotifyInternalActivation( EFalse, aComponentId ); + } + else + { + OstTrace0( TRACE_IMPORTANT , DBTRACEOSTCATEGORYBITMAP_ACTIVATETRACE_INVALID_GROUP,"DBTraceOstCategoryBitmap::ActivateTrace - Invalid group ID"); + // Notifies activation interfaces of invalid group ID + DTraceCore* traceCore = DTraceCore::GetInstance(); + if ( traceCore != NULL ) + { + traceCore->GetNotifier().TraceError( aComponentId, aGroupId, KErrArgument ); + } + } + } + +/** + * Deactivate trace group + * + * @param aComponentId The component ID + * @param aGroupId The group ID + */ +void DBTraceOstCategoryBitmap::DeactivateTrace(const TUint32 aComponentId, const TUint32 aGroupId) + { + OstTraceExt2( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_DEACTIVATETRACE_ENTRY,"> DBTraceOstCategoryBitmap::DeactivateTrace. CID:0x%x GID:0x%x", aComponentId, aGroupId ); + if (ComponentIdIsValid(aComponentId) ) + { + if (GroupIdIsValid(aGroupId)) + { + + TInt componentIndex = FindComponentId(aComponentId, *iOstComponents); + if (componentIndex >= 0) + { + CopyArray(iOstComponents, iTmpArray); + CleanupComponentsArray(*iChangedArray); + RemoveGroupId(aComponentId, aGroupId, componentIndex, *iTmpArray, *iChangedArray); + if ((*iTmpArray)[ componentIndex ].iGroups.Count() == 0) + { + RemoveComponentId(aComponentId, EFalse, *iTmpArray, *iChangedArray); + } + + //Swap pointers. + SetNewComponentsArrayPtr( iTmpArray ); + + //notify internal listeners and update internal activation cache + HandleTraceActivationChanges(*iChangedArray); + NotifyInternalActivation( EFalse, aComponentId ); + } + } + else + { + OstTrace0( TRACE_IMPORTANT , DBTRACEOSTCATEGORYBITMAP_DEACTIVATETRACE_INVALID_GROUP,"DBTraceOstCategoryBitmap::DeactivateTrace - Invalid group ID"); + // Notifies activation interfaces of invalid group ID + DTraceCore* traceCore = DTraceCore::GetInstance(); + if ( traceCore != NULL ) + { + traceCore->GetNotifier().TraceError( aComponentId, aGroupId, KErrArgument ); + } + } + } + } + +/** + * Deactivates all groups from a component + * + * @param aComponentId The component ID + */ +void DBTraceOstCategoryBitmap::DeactivateAll(const TUint32 aComponentId) + { + OstTrace1( TRACE_IMPORTANT , DBTRACEOSTCATEGORYBITMAP_DEACTIVATEALL_ENTRY,"> DBTraceOstCategoryBitmap::DeactivateAll. CID:0x%x", aComponentId ); + + CopyArray(iOstComponents, iTmpArray); + CleanupComponentsArray(*iChangedArray); + + if( RemoveComponentId(aComponentId, ETrue, *iTmpArray, *iChangedArray) != KErrNotFound) + SetNewComponentsArrayPtr( iTmpArray ); + + //notify internal listeners and update internal activation cache + HandleTraceActivationChanges(*iChangedArray); + NotifyInternalActivation( EFalse, aComponentId ); + } + +/** + * Reads the bitmap from the settings. If the settings does + * not have a bitmap, the current bitmap is written to it + * + * @param aSettings the settings + */ +void DBTraceOstCategoryBitmap::ReadFromSettings(DTraceCoreSettings& aSettings) + { + // Read buffer + if ( aSettings.Read( iActivationBuffer, KMaxActivationBufferLength ) ) + { + CopyArray(iOstComponents, iTmpArray); + CleanupComponentsArray(*iChangedArray); + + TUint8* ptr = iActivationBuffer; + TInt componentcount = Read32FromBuffer(ptr); + TC_TRACE( ETraceLevelFlow, Kern::Printf( " DBTraceOstCategoryBitmap::ReadFromSettings() components=%d", componentcount ) ); + TInt groupcount = 0; + TUint32 componentID = 0; + TUint16 groupID = 0; + TInt index = 0; + for ( TInt i = 0; i < componentcount; ++i ) + { + // Read number of group IDs (4 bytes) + groupcount = Read32FromBuffer(ptr); + // Read component ID (4 bytes) + componentID = Read32FromBuffer(ptr); + index = AddComponentId(componentID, *iTmpArray); + // Read group IDs (2 bytes each) + for ( TInt k = 0; k < groupcount; ++k ) + { + groupID = Read16FromBuffer(ptr); + if (GroupIdIsValid(groupID)) + { + AddGroupId(componentID, groupID, index, *iTmpArray, *iChangedArray); + } + else + { + // Notifies activation interfaces of invalid group ID + DTraceCore* traceCore = DTraceCore::GetInstance(); + if ( traceCore != NULL ) + { + traceCore->GetNotifier().TraceError( componentID, groupID, KErrArgument ); + } + } + } + } + + //swap pointers and clean up + SetNewComponentsArrayPtr( iTmpArray ); + HandleTraceActivationChanges(*iChangedArray); + NotifyInternalActivation( ETrue, componentID ); + } + } + +/** + * Writes the bitmap to given settings + * + * @param aSettings the settings where bitmap is written + */ +void DBTraceOstCategoryBitmap::WriteToSettings(DTraceCoreSettings& aSettings) + { + TUint8* ptr = iActivationBuffer; + TInt componentcount = iOstComponents->Count(); + WriteToBuffer(ptr, (TUint32)(componentcount)); + for ( TInt i = 0; i < componentcount; ++i ) + { + // Add number of group IDs (4 bytes) + TInt groupcount = (*iOstComponents)[i].iGroups.Count(); + WriteToBuffer(ptr, (TUint32)(groupcount)); + // Add component ID (4 bytes) + WriteToBuffer(ptr, (*iOstComponents)[i].iComponentId); + TC_TRACE( ETraceLevelFlow, Kern::Printf( " DBTraceOstCategoryBitmap::WriteToSettings() component=0x%x with %d groups",(*iOstComponents)[i].iComponentId, groupcount ) ); + // Add group IDs (2 bytes each) + for ( TInt k = 0; k < groupcount; ++k ) + { + WriteToBuffer(ptr, (TUint16)((*iOstComponents)[i].iGroups[k]) ); + } + } + // Save buffer + aSettings.Write( iActivationBuffer, KMaxActivationBufferLength ); + } + +/** + * Checks if trace points with a specific component ID and group ID are + * currently active + * + * @param aComponentId The component ID + * @param aTraceWord The trace word containing the group ID to check + * @return ETrue if trace is active, EFalse if not + */ +TBool DBTraceOstCategoryBitmap::IsTraceActivated(const TUint32 aComponentId, TUint32 aTraceWord) + { + // Find component + TOstComponent ostComponent; + ostComponent.iComponentId = aComponentId; + TInt irq = ReadLock(); + TInt index = iOstComponents->FindInUnsignedKeyOrder(ostComponent); + if (index != KErrNotFound) + { + index = (*iOstComponents)[ index ].iGroups.FindInOrder((aTraceWord & GRP_MASK) >> GRP_SHIFT); + } + TBool ret = (index != KErrNotFound ); + ReadUnlock(irq); + return ret; + } + +/** + * Find component id index in array + * + * @param aComponentId Component id to be searched + * @param aOstComponents Array to search through + * @return index of component id in array if found, otherwise KErrNotFound + */ +TInt DBTraceOstCategoryBitmap::FindComponentId(TUint32 aComponentId, RArray& aOstComponents) + { + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_FINDCOMPONENTID_ENTRY,"> DBTraceOstCategoryBitmap::FindComponentId 0x%x", aComponentId ); + TOstComponent tempComponent; + tempComponent.iComponentId = aComponentId; + // Check index of component id in array + TInt index = aOstComponents.FindInUnsignedKeyOrder(tempComponent); + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_FINDCOMPONENTID_EXIT,"< DBTraceOstCategoryBitmap::FindComponentId. Index:%d", index ); + return index; + } + +/** + * Add component id to array + * + * @param aComponentId Component id to be added + * @return index of (added of existing) component id in array or an error code + */ +TInt DBTraceOstCategoryBitmap::AddComponentId(TUint32 aComponentId, RArray& aOstComponents) + { + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_ADDCOMPONENTID_ENTRY,"> DBTraceOstCategoryBitmap::AddComponentId 0x%x", aComponentId ); + TOstComponent tempComponent; + tempComponent.iComponentId = aComponentId; + TInt index(KErrNotFound); + // Add component id + TInt err = aOstComponents.InsertInUnsignedKeyOrder(tempComponent); + OstTraceExt2( TRACE_IMPORTANT , DBTRACEOSTCATEGORYBITMAP_ADDCOMPONENTID_INSERT_FAILED,"DBTraceOstCategoryBitmap::AddComponentId - Insert returned. CID:0x%x Err:%d",(TUint)aComponentId, (TInt)err ); + if ( (err == KErrNone ) || (err == KErrAlreadyExists )) + { + // Check index of component id in array + index = aOstComponents.FindInUnsignedKeyOrder(tempComponent); + } + + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_ADDCOMPONENTID_EXIT,"< DBTraceOstCategoryBitmap::AddComponentId. Index:%d", index ); + return index; + } + +/** + * Remove component id in array. + * + * @param aComponentId Component id to be removed + * @param aNotifyActivationListeners if true, inform activation notification listeners + * @param aOstComponents array from which component has to be removed + * @param aChangedArray Array that will be updated to contain the changed TOstComponent objects + * @return index of removed component id if found, otherwise KErrNotFound + */ +TInt DBTraceOstCategoryBitmap::RemoveComponentId(TUint32 aComponentId, TBool aNotifyActivationListeners, + RArray& aOstComponents, RArray< TOstComponent >& aChangedArray ) + { + OstTraceExt2( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_REMOVECOMPONENTID_ENTRY, "> DBTraceOstCategoryBitmap::RemoveComponentId 0x%x %d", aComponentId, aNotifyActivationListeners ); + + // Check index of component id in array + TInt index = FindComponentId(aComponentId, aOstComponents); + if (index >= 0) + { + // Component id found - Remove it + aOstComponents.Remove(index); + + // Inform about removal if aNotifyActivationListeners is true + if ( aNotifyActivationListeners ) + { + AddGroupToChangedArray(aChangedArray, aComponentId, KAllGroups); + } + } + + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_REMOVECOMPONENTID_EXIT,"< DBTraceOstCategoryBitmap::RemoveComponentId. Index:%d", index ); + return index; + } + +/** + * Adds group id to array + * + * @param aComponentId Component where the group belongs + * @param aGroupId Group id to be added + * @param aIndex Index of component array where to add the groupId + * @param aOstComponents Array with TOstComponent objects. + * @param aChangedArray Array that will be updated to contain the changed TOstComponent objects + */ +TInt DBTraceOstCategoryBitmap::AddGroupId(TUint32 aComponentId, TGroupId aGroupId, TInt aIndex, + RArray& aOstComponents, RArray& aChangedArray) + { + OstTraceExt2( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_ADDGROUPID_ENTRY,"> DBTraceOstCategoryBitmap::AddGroupId. GID:0x%x. Index:%d", (TUint32) aGroupId, (TUint32) aIndex ); + TInt ret = KErrNone; + + if (aIndex >= 0 && aIndex < aOstComponents.Count() ) + { + // Add group Id + ret = aOstComponents[ aIndex ].iGroups.InsertInOrder(aGroupId); + if (ret == KErrNone) + { + // Inform notifier that trace has been activated + DTraceCore* traceCore = DTraceCore::GetInstance(); + if (traceCore != NULL) + { + // Don't activate Kernel groups from BTrace here, it will be done in KernelHandler + if ((TUint) aGroupId > KMaxKernelCategory) + { + BTrace::SetFilter((TUint) aGroupId, 1); + } + + // Add group to changed array + AddGroupToChangedArray(aChangedArray, aComponentId, aGroupId); + } + else + { + ret = KErrGeneral; + } + } + else + if (ret == KErrAlreadyExists) + { + ret = KErrNone; + } + } + else + { + ret = KErrArgument; + } + + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_ADDGROUPID_EXIT,"< DBTraceOstCategoryBitmap::AddGroupId. Ret:%d", ret ); + return ret; + } + +/** + * Removes group id from array + * + * @param aComponentId Component where the group belongs + * @param aGroupId Group id to be removed + * @param aIndex Index of component array from where to remove the groupId + * @param aOstComponents Array with TOstComponent objects. + * @param aChangedArray Array that will be updated to contain the changed TOstComponent objects + */ +TInt DBTraceOstCategoryBitmap::RemoveGroupId(TUint32 aComponentId, TGroupId aGroupId, TInt aIndex, + RArray& aOstComponents, RArray< TOstComponent >& aChangedArray) + { + OstTraceExt2( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_REMOVEGROUPID_ENTRY,"> DBTraceOstCategoryBitmap::RemoveGroupId. GID:0x%x. Idx:%d", (TUint32) aGroupId, (TUint32) aIndex ); + TInt ret = KErrNone; + if (aIndex >= 0 && aIndex < aOstComponents.Count() ) + { + // Component id found, remove group ID + TInt groupIndex = aOstComponents[ aIndex ].iGroups.FindInOrder(aGroupId); + if (groupIndex >= 0) + { + aOstComponents[ aIndex ].iGroups.Remove(groupIndex); + // Inform notifier that trace has been deactivated + DTraceCore* traceCore = DTraceCore::GetInstance(); + if (traceCore != NULL) + { + BTrace::SetFilter((TUint) aGroupId, 0); + OstTrace1( TRACE_INTERNAL, DBTRACEOSTCATEGORYBITMAP_REMOVEGROUPID_NOTIFIER_DEACTIVATED,"DBTraceOstCategoryBitmap::RemoveGroupId - Group deactivated, calling notifier. GID:0x%x",(TUint32) aGroupId ); + + AddGroupToChangedArray(aChangedArray, aComponentId, aGroupId); + ret = KErrNone; + } + else + { + ret = KErrGeneral; + } + } + else + { + ret = KErrNone; + } + } + else + { + ret = KErrArgument; + } + + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_REMOVEGROUPID_EXIT,"< DBTraceOstCategoryBitmap::RemoveGroupId. Ret:%d", ret ); + return ret; + } + +/** + * Read OST Protocol frame from OST protocol message. + * + * @pre On entry to this methods writer mutex (iActivationWriteLock) must be held. + * + * @param aMessage Received message + * @param aFrameStartIndex Start offset of the frame in message + * @return Offset after read frame + */ +TInt DBTraceOstCategoryBitmap::ReadOstProtocolFrame(const TDesC8& aMessage, TUint32 aFrameStartIndex) + { + OstTraceExt2( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_READOSTPROTOCOLFRAME_ENTRY, "< DBTraceOstCategoryBitmap::ReadOstProtocolFrame. aMessage:%s, aFrameStartIndex:%u", aMessage,aFrameStartIndex ); + + //__ASSERT_MUTEX(iActivationWriteLock); + TInt retPosition = 0; + TInt length = aMessage.Length(); + + TInt ostBaseHeaderSize = OstHeader::OstBaseProtocol::KOstBaseHeaderSize; + TInt applicationIdOffset = OstHeader::OstTraceActivation::SetApplicationStatusRequest::KApplicationIdOffset-ostBaseHeaderSize; + TInt activationStatusOffset = + OstHeader::OstTraceActivation::SetApplicationStatusRequest::KActivationStatusOffset-ostBaseHeaderSize; + + TInt groupIdOffset = OstHeader::OstTraceActivation::SetApplicationStatusRequest::KGroupIdOffset-ostBaseHeaderSize; + TInt activated = OstConstants::OstTraceActivation::ActivationStatus::KApplicationTracesActivated; + TInt deactivated = OstConstants::OstTraceActivation::ActivationStatus::KApplicationTracesDeactivated; + + // Checks that buffer is large enough for the frame + if (length >= (activationStatusOffset +1 /*1==activatin status size*/- ostBaseHeaderSize )) + { + const TUint8* frameStart = aMessage.Ptr() + aFrameStartIndex; + // Check if activation or deactivation + TUint8 activationStatus = *(frameStart + activationStatusOffset ); + + if ( (activationStatus == activated ) || (activationStatus == deactivated )) + { + // One frame may contain multiple group ID's. Each occupy 2 bytes + TUint32 numberOfGroups = (length-groupIdOffset)/2; // CodForChk_Dis_Magic + + if ((length-groupIdOffset)%2!=0) // CodForChk_Dis_Magic + { + numberOfGroups--; + } + // One frame contains one component id + TUint32 applicationId = Read32(frameStart + applicationIdOffset); + + // Swap byte order + applicationId = SWAP32( applicationId ); + + CopyArray(iOstComponents, iTmpArray); + CleanupComponentsArray(*iChangedArray); + + TInt index(0); + if (activationStatus == activated) + { + index = AddComponentId(applicationId, *iTmpArray); + } + else + { + index = FindComponentId(applicationId, *iTmpArray); + } + + if (index >= 0) + { + // Updates the group ID's that have changed + retPosition = ReadOstProtocolFrameGroups(aMessage, aFrameStartIndex, activationStatus, index, applicationId, *iTmpArray, *iChangedArray); + aFrameStartIndex = retPosition; + } + else + { + OstTrace1( TRACE_INTERNAL, DBTRACEOSTCATEGORYBITMAP_READOSTFRAME_NOT_FOUND,"DBTraceOstCategoryBitmap::ReadOstFrame - Component ID not found: 0x%x", applicationId ); + } + + //swap pointers and cleanup + SetNewComponentsArrayPtr(iTmpArray); + + //notify internal listeners and update internal activation cache + HandleTraceActivationChanges(*iChangedArray); + NotifyInternalActivation( EFalse, applicationId ); + + } + } + + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_READOSTFRAME_EXIT, "< DBTraceOstCategoryBitmap::ReadOstFrame. Ret:%d", retPosition ); + return retPosition; + } + +/** + * Read the groups from an OST frame + * + * @param aMessage Received message + * @param aFrameStartIndex Start offset of the frame in message + * @param aActivationInfo Activation / deactivation flag + * @param aComponentIndex The index of the component where the groups belong to + * @param aComponentId The component ID + * @param aOstComponents Array with TOstComponent objects. + * @param aChangedArray Array that will be updated to contain the changed TOstComponent objects + * @return Offset after read frame + */ +TInt DBTraceOstCategoryBitmap::ReadOstProtocolFrameGroups(const TDesC8& aMessage, TInt aFrameStartIndex, TUint8 aActivationInfo, + TInt aComponentIndex, TUint32 aComponentId, RArray& aOstComponents, RArray< TOstComponent >& aChangedArray) + { + OstTraceExt3( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_READOSTPROTOCOLFRAMEGROUPS_ENTRY,"< DBTraceOstCategoryBitmap::ReadOstProtocolFrameGroups. aMessage:%s, aFrameStartIndex:%u, aActivationInfo:%u", aMessage,aFrameStartIndex, aActivationInfo ); + + TInt length(aMessage.Length() ); + TInt ostBaseHeaderSize = OstHeader::OstBaseProtocol::KOstBaseHeaderSize; + TInt groupIdOffset = OstHeader::OstTraceActivation::SetApplicationStatusRequest::KGroupIdOffset-ostBaseHeaderSize; + TInt activated = OstConstants::OstTraceActivation::ActivationStatus::KApplicationTracesActivated; + TInt deactivated = OstConstants::OstTraceActivation::ActivationStatus::KApplicationTracesDeactivated; + + const TUint8* frameStart = aMessage.Ptr() + aFrameStartIndex; + + TInt offset = groupIdOffset; + TInt retPosition( 0); + + // One frame may contain multiple group ID's. Each occupy 2 bytes + TUint32 numberOfGroups = (length-groupIdOffset) / 2; // CodForChk_Dis_Magic + + if ((length-groupIdOffset) % 2 != 0) // CodForChk_Dis_Magic + { + numberOfGroups--; + } + + TBool swapGroups = ETrue; + // This is supporting both byte orders + if (numberOfGroups > KMaxGroupId) + { + swapGroups = ETrue; + numberOfGroups = SWAP32( numberOfGroups ); + } + + // Read Group ids and remove from array + for (TUint i = 0; i < numberOfGroups; i++) + { + TUint16 groupId = Read16(frameStart + offset); + if (swapGroups) + { + groupId = SWAP16( groupId ); + } + offset += KGroupIdLength; + if (GroupIdIsValid(groupId)) + { + if (aActivationInfo == activated) + { + AddGroupId(aComponentId, groupId, aComponentIndex, aOstComponents, aChangedArray); + } + else + { + RemoveGroupId(aComponentId, groupId, aComponentIndex, aOstComponents, aChangedArray); + } + } + else + { + // Notifies activation interfaces of invalid group ID + DTraceCore* traceCore = DTraceCore::GetInstance(); + if ( traceCore != NULL ) + { + traceCore->GetNotifier().TraceError( aComponentId, groupId, KErrArgument ); + } + } + } + // If all groups were removed from the component, it can also be removed + if ( (aActivationInfo == deactivated ) && (aOstComponents[ aComponentIndex ].iGroups.Count() == 0 )) + { + RemoveComponentId(aComponentId, EFalse, aOstComponents, aChangedArray); + } + // The next frame offset is returned + retPosition = aFrameStartIndex + offset; + + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_READOSTPROTOCOLFRAMEGROUPS_EXIT,"< DBTraceOstCategoryBitmap::ReadOstFrameGroups. Ret:%d", retPosition ); + return retPosition; + } + +/** + * Read OST frame from ISI message. + * + * @pre On entry to this methods writer mutex (iActivationWriteLock) must be held. + * + * @param aMessage Received message + * @param aFrameStartIndex Start offset of the frame in message + * @return Offset after read frame + */ +TInt DBTraceOstCategoryBitmap::ReadOstFrame(const TDesC8& aMessage, TUint32 aFrameStartIndex) + { + TInt retPosition = 0; + TUint length = aMessage.Length(); + // Checks that buffer is large enough for the frame + if (length >= (aFrameStartIndex + KOstMinFrameLength )) + { + const TUint8* frameStart = aMessage.Ptr() + aFrameStartIndex; + // Check if activation or deactivation + TUint8 activationInfo = *(frameStart + KOstActivationInfoOffset ); + + if ( (activationInfo == SOS_MON_TRACECORE_OST_DEACTIVATE ) || (activationInfo == SOS_MON_TRACECORE_OST_ACTIVATE ) + || (activationInfo == SOS_MON_TRACECORE_OST_OVERWRITE )) + { + // One frame may contain multiple group ID's. Each occupy 2 bytes + (void) Read32(frameStart + KOstNumberOfGroupsOffset); // This is the numberOfGroups + // One frame contains one component id + TUint32 componentId = Read32(frameStart + KOstComponentIdOffset); + // Component Id in message is in Big Endian format so it need to be swap to Little Endian format + componentId = SWAP32( componentId ); + + CopyArray(iOstComponents, iTmpArray); + CleanupComponentsArray(*iChangedArray); + + TInt index( 0); + if ( (activationInfo == SOS_MON_TRACECORE_OST_ACTIVATE ) || (activationInfo == SOS_MON_TRACECORE_OST_OVERWRITE )) + { + index = AddComponentId(componentId, *iTmpArray); + } + else + { + index = FindComponentId(componentId, *iTmpArray); + } + if (index >= 0) + { + // Updates the group ID's that have changed + retPosition = ReadOstFrameGroups(aMessage, aFrameStartIndex, activationInfo, index, componentId, *iTmpArray, *iChangedArray); + } + + //swap pointers and cleanup + SetNewComponentsArrayPtr(iTmpArray); + + //notify internal listeners and update internal activation cache + HandleTraceActivationChanges(*iChangedArray); + NotifyInternalActivation( EFalse, componentId ); + } + else + if (activationInfo == SOS_MON_TRACECORE_OST_DEACTIVATE_ALL) + { + // Deactivate all groups from component + TUint32 componentId = Read32(frameStart + KOstComponentIdOffset); + // Component Id in message is in Big Endian format so it need to be swap to Little Endian format + componentId = SWAP32( componentId ); + + CopyArray(iOstComponents, iTmpArray); + CleanupComponentsArray(*iChangedArray); + RemoveComponentId(componentId, ETrue, *iTmpArray, *iChangedArray); + SetNewComponentsArrayPtr(iTmpArray); + + //notify internal listeners and update internal activation cache + HandleTraceActivationChanges(*iChangedArray); + NotifyInternalActivation( EFalse, componentId ); + } + } + + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_READOSTFRAME_EXIT_,"< DBTraceOstCategoryBitmap::ReadOstFrame position:%d", retPosition ); + return retPosition; + } + +/** + * Read the groups from an OST frame + * + * @param aMessage Received message + * @param aFrameStartIndex Start offset of the frame in message + * @param aActivationInfo Activation / deactivation flag + * @param aComponentIndex The index of the component where the groups belong to + * @param aComponentId The component ID + * @param aOstComponents Array with TOstComponent objects. + * @param aChangedArray Array with changed TOstComponent objects. + * @return Offset after read frame + */ +TInt DBTraceOstCategoryBitmap::ReadOstFrameGroups(const TDesC8& aMessage, TInt aFrameStartIndex, TUint8 aActivationInfo, + TInt aComponentIndex, TUint32 aComponentId, RArray& aOstComponents, RArray< TOstComponent >& aChangedArray) + { + OstTraceExt2( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_READOSTFRAMEGROUPS_ENTRY,"> DBTraceOstCategoryBitmap::ReadOstFrameGroups startIdx:%d componentIdx:%d", aFrameStartIndex, aComponentIndex ); + + const TUint8* frameStart = aMessage.Ptr() + aFrameStartIndex; + TUint frameLen(aMessage.Length() - aFrameStartIndex); + TUint offset = KOstGroupIdOffset; + TInt retPosition( 0); + // One frame may contain multiple group ID's. Each occupy 2 bytes + TUint32 numberOfGroups = Read32(frameStart + KOstNumberOfGroupsOffset); + + TUint i = 0; + + // Number of groups in message is in Big Endian format so it need to be swap to Little Endian format + numberOfGroups = SWAP32( numberOfGroups ); + + if (frameLen >= (offset + numberOfGroups * KGroupIdLength )) + { + if (aActivationInfo == SOS_MON_TRACECORE_OST_OVERWRITE) + { + offset = OverwriteGroups(frameStart, aComponentIndex, aComponentId, numberOfGroups, aOstComponents, aChangedArray); + } + else + if (aActivationInfo == SOS_MON_TRACECORE_OST_DEACTIVATE || aActivationInfo == SOS_MON_TRACECORE_OST_ACTIVATE) + { + // Read Group ids and remove from array + for (i = 0; i < numberOfGroups; i++) + { + TUint16 groupId = Read16(frameStart + offset); + // Group Id in message is in Big Endian format so it need to be swap to Little Endian format + groupId = SWAP16( groupId ); + + offset += KGroupIdLength; + if (GroupIdIsValid(groupId)) + { + if (aActivationInfo == SOS_MON_TRACECORE_OST_ACTIVATE) + { + AddGroupId(aComponentId, groupId, aComponentIndex, aOstComponents, aChangedArray); + } + else + { + RemoveGroupId(aComponentId, groupId, aComponentIndex, aOstComponents, aChangedArray); + } + } + else + { + // Notifies activation interfaces of invalid group ID + DTraceCore* traceCore = DTraceCore::GetInstance(); + if ( traceCore != NULL ) + { + traceCore->GetNotifier().TraceError( aComponentId, groupId, KErrArgument ); + } + } + } + } + else + { + OstTrace1( TRACE_IMPORTANT , DBTRACEOSTCATEGORYBITMAP_READOSTFRAMEGROUPS__,"DBTraceOstCategoryBitmap::ReadOstFrameGroups - Unknow activation type %d", aActivationInfo); + } + + // If all groups were removed from the component, it can also be removed + if ( ( (aActivationInfo == SOS_MON_TRACECORE_OST_DEACTIVATE ) || (aActivationInfo == SOS_MON_TRACECORE_OST_OVERWRITE ) ) + && (aOstComponents[ aComponentIndex ].iGroups.Count() == 0 )) + { + RemoveComponentId(aComponentId, EFalse, aOstComponents, aChangedArray); + } + // The next frame offset is returned + retPosition = aFrameStartIndex + offset; + } + else + { + OstTraceExt2( TRACE_IMPORTANT , DBTRACEOSTCATEGORYBITMAP_READOSTFRAME_TOO_SHORT_FRAME,"DBTraceOstCategoryBitmap::ReadOstFrame - Too short frame nrOfGroups:%u len:%d",numberOfGroups, (TInt32)frameLen ); + } + OstTrace1( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_READOSTFRAMEGROUPS_EXIT_,"< DBTraceOstCategoryBitmap::ReadOstFrameGroups position:%d", retPosition ); + return retPosition; + } + +/** + * Callback when a trace activation message is received + * + * @param aMsg Reference to message + */ +void DBTraceOstCategoryBitmap::MessageReceived(TTraceMessage &aMsg) + { + TInt len(aMsg.iData->Length() ); + + // Message header is in proprietary format + if (aMsg.iMsgFormat == EMessageHeaderFormatProprietary) + { + + // Check that message length is big enough + if (len >= KOstMinFrameLength) + { + // Get OST message ID + TUint8 ostMessageId = *(aMsg.iData->Ptr() + KOstMessageIdOffset ); + switch (ostMessageId) + { + case SOS_MON_TRACECORE_OST_ACTIVATION: + { + TInt nextFrameStart( 0); + TInt lastFrameStart( -1); + + // Go through OST frames + while (lastFrameStart < nextFrameStart) + { + lastFrameStart = nextFrameStart; + nextFrameStart = ReadOstFrame( *aMsg.iData, nextFrameStart); + } + break; + } + case SOS_MON_TRACECORE_OST_ACTIVATION_QUERY: + { + OstTrace0( TRACE_NORMAL, DBTRACEOSTCATEGORYBITMAP_MESSAGERECEIVED_ACTIVATION_QUERY_NOT_IMPLEMENTED,"DBTraceOstCategoryBitmap::MessageReceived - Activation query not implemented"); + break; + } + default: + { + OstTrace1( TRACE_IMPORTANT , DBTRACEOSTCATEGORYBITMAP_MESSAGERECEIVED_INVALID_MESSAGE_ID,"DBTraceOstCategoryBitmap::MessageReceived - Invalid message ID - %d", ostMessageId); + break; + } + } + } + } + + // Message header is in OST format + else + if (aMsg.iMsgFormat == EMessageHeaderFormatOst) + { + OstProtocolMessage(aMsg); + } + } + +/** + * Ost Protocol Message handler + * + * @param aMessage The message + */ +void DBTraceOstCategoryBitmap::OstProtocolMessage(TTraceMessage &aMsg) + { + if ((*aMsg.iData)[OstHeader::OstTraceActivation::KOstHeaderMessageIdOffset-OstHeader::OstBaseProtocol::KOstBaseHeaderSize] + == OstConstants::OstTraceActivation::KSetApplicationStatusRequest) + { + ReadOstProtocolFrame( *aMsg.iData, 0); + + // Send KSetApplicationResponse + TBuf8<256> responseMessageHeader; // CodForChk_Dis_Magic + responseMessageHeader.Append(OstConstants::KOstHeaderVersion); + responseMessageHeader.Append(OstConstants::OstBaseProtocol::KOstTraceActivationProtocol); // + responseMessageHeader.Append( 0); // Data size MSB + responseMessageHeader.Append( 4); // Data size LSB // CodForChk_Dis_Magic + + TBuf8<256> responseMessageData; // CodForChk_Dis_Magic + TInt headerSize = + OstHeader::OstTraceActivation::KOstHeaderTransactionIdOffset-OstHeader::OstBaseProtocol::KOstBaseHeaderSize; + responseMessageData.Append((*aMsg.iData)[headerSize]); + responseMessageData.Append(OstConstants::OstTraceActivation::KSetApplicationStatusResponse); + responseMessageData.Append( 0x00); // Response request succeded TODO add constant to header + responseMessageData.Append( 0x00); // Filler + + // Create TraceMessage + TTraceMessage msg; + msg.iMsgFormat = EMessageHeaderFormatOst; + msg.iHeader = &responseMessageHeader; + msg.iData = &responseMessageData; + msg.iMessageId = OstConstants::OstTraceActivation::KSetApplicationStatusResponse; + DTraceCoreActivationBase::SendResponse(msg); + } + } + +/** + * Overwite trace groups + * + * @param aComponentIndex The index of the component where the groups belong to + * @param aComponentId The component ID + * @param numberOfGroups Number of groups in overwrite message + * @param aOstComponents Array with TOstComponent objects. + * @param aChangedArray Array with changed TOstComponent objects. + * @return Offset after read frame + */ +TInt DBTraceOstCategoryBitmap::OverwriteGroups(const TUint8* aFrameStart, TInt aComponentIndex, TUint32 aComponentId, + TUint32 numberOfGroups, RArray& aOstComponents, RArray< TOstComponent >& aChangedArray) + { + OstTraceExt3( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_OVERWRITEGROUPS_ENTRY,"> DBTraceOstCategoryBitmap::OverwriteGroups. ComponentIdx:%d CID:0x%x NoOfGroups:%u",(TInt)aComponentIndex, (TUint)aComponentId , (TUint)numberOfGroups ); + RArray groupsInMessage; + TInt ret = 0; + TUint i = 0; + TUint offset = KOstGroupIdOffset; + + // Read Group ids and remove from array + for (i = 0; i < numberOfGroups; i++) + { + TUint16 groupId = Read16(aFrameStart + offset); + // Group Id in message is in Big Endian format so it need to be swap to Little Endian format + groupId = SWAP16( groupId ); + + offset += KGroupIdLength; + + ret = groupsInMessage.InsertInOrder(groupId); + } + + + TUint numberOfGroupsInComponent = aOstComponents[ aComponentIndex ].iGroups.Count(); + TUint numberOfRemovedGroups = 0; + + // First remove those groups that are not any more activated + for (i = 0; i < numberOfGroupsInComponent; i++) + { + + ret = groupsInMessage.FindInOrder(aOstComponents[ aComponentIndex ].iGroups[ i - numberOfRemovedGroups ]); + + if (ret == KErrNotFound) + { + RemoveGroupId(aComponentId, aOstComponents[ aComponentIndex ].iGroups[ i - numberOfRemovedGroups ], aComponentIndex, + aOstComponents, aChangedArray); + numberOfRemovedGroups++; + } + } + + // Add groups that are not already added + numberOfGroups = groupsInMessage.Count(); + for (i = 0; i < numberOfGroups; i++) + { + ret = aOstComponents[ aComponentIndex ].iGroups.FindInOrder(groupsInMessage[ i ]); + + if (ret == KErrNotFound) + { + if (GroupIdIsValid(groupsInMessage[ i ])) + { + + AddGroupId(aComponentId, groupsInMessage[ i ], aComponentIndex, aOstComponents, aChangedArray); + } + else + { + OstTrace1( TRACE_ERROR, DBTRACEOSTCATEGORYBITMAP_OVERWRITEGROUPS_ERROR, "DBTraceOstCategoryBitmap::OverwriteGroups - Invalid group ID: 0x%x", groupsInMessage[ i ] ); + // Notifies activation interfaces of invalid group ID + DTraceCore* traceCore = DTraceCore::GetInstance(); + if ( traceCore != NULL ) + { + traceCore->GetNotifier().TraceError( aComponentId, groupsInMessage[ i ], KErrArgument ); + } + } + } + } + + groupsInMessage.Close(); + OstTraceExt2( TRACE_FLOW, DBTRACEOSTCATEGORYBITMAP_OVERWRITEGROUPS_EXIT,"< DBTraceOstCategoryBitmap::OverwriteGroups. Offset:%u, ret:%d", offset, ret ); + return offset; + + } + +/** + * Checks if a component ID is supported by this activation object + * + * @param aComponentID the component ID to be checked + * @return ETrue if supported, EFalse if not + */ +TBool DBTraceOstCategoryBitmap::IsComponentSupported(TUint32 /*aComponentID*/) + { + // All components are supported + return ETrue; + } + +/** + * Allocates memory for activation buffer + * + * @return KErrNone if allocation succesfull otherwise KErrNoMemory + */ +TInt DBTraceOstCategoryBitmap::AllocateActivationBuffer() + { + TInt ret = KErrNone; + iActivationBuffer = ( TUint8* )Kern::Alloc( KMaxActivationBufferLength ); + if ( iActivationBuffer == NULL ) + { + ret = KErrNoMemory; + } + return ret; + } + +/** + * Read and write helper functions for activation buffer + */ +TUint32 DBTraceOstCategoryBitmap::Read32FromBuffer(TUint8*& aPtr) + { + TUint32 ret = 0; + if ( aPtr >= iActivationBuffer + && aPtr < iActivationBuffer+KMaxActivationBufferLength-K4Bytes) + { + ret = Read32(aPtr); + aPtr += K4Bytes; + } + return ret; + } + +TUint16 DBTraceOstCategoryBitmap::Read16FromBuffer(TUint8*& aPtr) + { + TUint16 ret = 0; + if ( aPtr >= iActivationBuffer + && aPtr < iActivationBuffer+KMaxActivationBufferLength-K2Bytes) + { + ret = Read16(aPtr); + aPtr += K2Bytes; + } + return ret; + } + +void DBTraceOstCategoryBitmap::WriteToBuffer(TUint8*& aPtr, TUint32 aData32) + { + if ( aPtr >= iActivationBuffer + && aPtr < iActivationBuffer+KMaxActivationBufferLength-K4Bytes) + { + *aPtr++ = aData32 & K8BitMask; + *aPtr++ = (aData32 >> K8BitShift) & K8BitMask; + *aPtr++ = (aData32 >> K16BitShift) & K8BitMask; + *aPtr++ = (aData32 >> K24BitShift) & K8BitMask; + } + } + +void DBTraceOstCategoryBitmap::WriteToBuffer(TUint8*& aPtr, TUint16 aData16) + { + if ( aPtr >= iActivationBuffer + && aPtr < iActivationBuffer+KMaxActivationBufferLength-K2Bytes) + { + *aPtr++ = aData16 & K8BitMask; + *aPtr++ = (aData16 >> K8BitShift) & K8BitMask; + } + } + +/** + * Handles trace activation changes + * + * @pre On entry to this method writer mutex (iActivationWriteLock) must be help. + * @param aChangedArray Array with changed TOstComponent objects. + */ +void DBTraceOstCategoryBitmap::HandleTraceActivationChanges(RArray< TOstComponent >& aChangedArray) + { + TC_TRACE( ETraceLevelFlow, Kern::Printf("Activated components count: %d", iOstComponents->Count())); + *(iBTraceOstCategoryHandler->iCacheItem1) = 0; + *(iBTraceOstCategoryHandler->iCacheItem2) = 0; + *(iBTraceOstCategoryHandler->iCacheItem3) = 0; + *(iBTraceOstCategoryHandler->iCacheItem4) = 0; + + TInt count = iOstComponents->Count(); + // No traces activated, use Dummy handler + if (count == 0) + { + iBTraceOstCategoryHandler->iAllTracesDeactivated = ETrue; + BTrace::SetHandler(DummyBTraceHandler); + TC_TRACE( ETraceLevelFlow, Kern::Printf("Dummy trace handler in use 1")); + } + + // Check if only printf traces are activated + else if (count == 1 && (*iOstComponents)[0].iComponentId == KKernelHooksOSTComponentUID) + { + + // Check if there are other groups than printfs activated + RArray< TUint > groups = (*iOstComponents)[0].iGroups; + TInt groupcount = groups.Count(); + TBool onlyPrintfs = ETrue; + for ( TInt i = 0; i < groupcount; ++i ) + { + if (groups[i] > BTrace::EPlatsecPrintf) + { + onlyPrintfs = EFalse; + break; + } + } + + // If there are only printfs, keep using Dummy handler + if (onlyPrintfs) + { + iBTraceOstCategoryHandler->iAllTracesDeactivated = ETrue; + BTrace::SetHandler(DummyBTraceHandler); + TC_TRACE( ETraceLevelFlow, Kern::Printf("Dummy trace handler in use 2")); + } + + // Something else than printfs activated, use normal handler + else + { + iBTraceOstCategoryHandler->iAllTracesDeactivated = EFalse; + BTrace::SetHandler(oldHandler); + TC_TRACE( ETraceLevelFlow, Kern::Printf("Normal trace handler in use 1")); + } + } + + // More than 1 component activated, use normal handler + else + { + iBTraceOstCategoryHandler->iAllTracesDeactivated = EFalse; + BTrace::SetHandler(oldHandler); + TC_TRACE( ETraceLevelFlow, Kern::Printf("Normal trace handler in use 2")); + } + + + // Notify listeners about the changed groups + DTraceCore* traceCore = DTraceCore::GetInstance(); + if ( traceCore != NULL ) + { + count = aChangedArray.Count(); + for (TInt i = 0; i < count; i++) + { + TUint32 componentId = aChangedArray[i].iComponentId; + RArray< TUint > groups = aChangedArray[i].iGroups; + TInt groupCount = groups.Count(); + for (TInt j=0;j < groupCount;j++) + { + TUint32 group = groups[j]; + + // Shift to be able to use IsTraceActivated function + if (IsTraceActivated(componentId, group << GRP_SHIFT)) + { + traceCore->GetNotifier().TraceActivated(componentId, group); + } + else + { + traceCore->GetNotifier().TraceDeactivated(componentId, group); + } + } + } + } + } + +/** + * Gets activated groups for this component ID + * @param aComponentId the component ID + */ +RArray< TUint > DBTraceOstCategoryBitmap::GetActivatedGroups( const TUint32 aComponentId ) + { + RArray< TUint > groups; + // Check index of component id in array + TInt index = FindComponentId(aComponentId, *iOstComponents); + if (index >= 0) + { + // Component id found, get groups + groups = (*iOstComponents)[ index ].iGroups; + } + return groups; + } + +/** + * Adds a group to array of changed activation groups + * @param aChangedArray Array with changed TOstComponent objects + * @param aComponentId Component ID + * @param aGroupId Group ID + */ +void DBTraceOstCategoryBitmap::AddGroupToChangedArray(RArray< TOstComponent >& aChangedArray, TUint32 aComponentId, TGroupId aGroupId) + { + TOstComponent newComponent; + newComponent.iComponentId = aComponentId; + aChangedArray.InsertInUnsignedKeyOrder(newComponent); + TInt changedIndex = FindComponentId(aComponentId, aChangedArray); + if(changedIndex != KErrNotFound) + aChangedArray[ changedIndex ].iGroups.InsertInOrder(aGroupId); + } + +/** +* Utility method to copy data between two RArray objects. +*/ +template +void DBTraceOstCategoryBitmap::CopyArray(RArray* aSrc, RArray* aDst) + { + aDst->Reset(); + TInt c = aSrc->Count(); + for(TInt i=0; iAppend( (*aSrc)[i] ); + } + + +//TODO: use this doxygen comment instead of old one +//TODO: don't pass any args as swap occurs only between iOstComponents and tmpArray +/** + * Sets new pointer for array with activated components. + * This operation is protected by spin lock on SMP systems. + * + * @param aNewPtr Pointer to new array containing TOstComponent objects. + */ +void DBTraceOstCategoryBitmap::SetNewComponentsArrayPtr(RArray*& aNewPtr) + { + TInt irq = ReadLock(); + RArray* tmpPtr = iOstComponents; + iOstComponents = aNewPtr; + aNewPtr = tmpPtr; + ReadUnlock(irq); + } + +/** + * Internal method to destroy array used to store activated components. + */ +void DBTraceOstCategoryBitmap::CleanupComponentsArray(RArray< TOstComponent >& aComponentArray) + { + TInt componentCount = aComponentArray.Count(); + for (TInt i=0; iClose(); + Kern::Free(iOstComponents); + iOstComponents = NULL; + } + + if(iTmpArray) + { + CleanupComponentsArray(*iTmpArray); + iTmpArray->Close(); + Kern::Free(iTmpArray); + iTmpArray = NULL; + } + + if (iChangedArray) + { + CleanupComponentsArray(*iChangedArray); + iChangedArray->Close(); + Kern::Free(iChangedArray); + iChangedArray = NULL; + } + } + +/** + * Reactivate all currently activated traces + * + * @return KErrNone if refresh successful + */ +TInt DBTraceOstCategoryBitmap::RefreshActivations() + { + RArray< TOstComponent >* tmpArray = new RArray(KOstComponentsArrayGranularity); + if(!tmpArray) + return KErrNoMemory; + + CopyArray(iOstComponents, tmpArray); + // Go through all components in array and refresh activations for each + TInt componentCount = tmpArray->Count(); + for (TInt i=0; i groups = (*tmpArray)[ i ].iGroups; + // Go through all groups for this component and refresh activations for each + TInt groupCount = groups.Count(); + for (TInt j=0; jClose(); + Kern::Free(tmpArray); + return KErrNone; + } + +// End of File