sl@0: // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: // WARNING: This file contains some APIs which are internal and are subject sl@0: // to change without notice. Such APIs should therefore not be used sl@0: // outside the Kernel and Hardware Services package. sl@0: // sl@0: sl@0: #ifndef D32BTRACE_H sl@0: #define D32BTRACE_H sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #ifndef __KERNEL_MODE__ sl@0: #include sl@0: #endif sl@0: sl@0: sl@0: class TBTraceBuffer; sl@0: sl@0: /** sl@0: Interface to the fast-trace memory buffer. sl@0: sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: class RBTrace : public RBusLogicalChannel sl@0: { sl@0: public: sl@0: /** sl@0: Bit flags indicating the operational mode of the fast-trace buffer. sl@0: */ sl@0: enum TMode sl@0: { sl@0: /** sl@0: Flag set to enable trace to be stored in the buffer. sl@0: If this is not set, all trace records are discarded. sl@0: */ sl@0: EEnable = 1<<0, sl@0: sl@0: /** sl@0: This flag dictates the behaviour which occurs when the trace buffer is too full to sl@0: accomodate a new record. sl@0: When this flag is set, new trace records will overwrite the oldest ones. sl@0: When this flag is not set, new trace records are discard. sl@0: (This latter mode provides the best performance.) sl@0: */ sl@0: EFreeRunning = 1<<1, sl@0: }; sl@0: sl@0: #ifndef __KERNEL_MODE__ sl@0: /** sl@0: Open channel to fast-trace driver. sl@0: Must be called before any other methods are used. sl@0: @return KErrNone or standard error code. sl@0: */ sl@0: IMPORT_C TInt Open(); sl@0: sl@0: /** sl@0: Close channel to fast-trace driver. sl@0: */ sl@0: IMPORT_C void Close(); sl@0: sl@0: /** sl@0: Get the current size of trace buffer. sl@0: @return Buffer size. sl@0: */ sl@0: IMPORT_C TInt BufferSize(); sl@0: sl@0: /** sl@0: Change size of trace buffer. sl@0: This causes all current data in the trace buffer to be lost. sl@0: If this method fails then the trace buffer may no longer exist. sl@0: @param aSize The size in bytes for the trace buffer. sl@0: @return KErrNone or standard error code. sl@0: */ sl@0: IMPORT_C TInt ResizeBuffer(TInt aSize); sl@0: sl@0: /** sl@0: Discard all trace data. sl@0: */ sl@0: IMPORT_C void Empty(); sl@0: sl@0: /** sl@0: The chunk in which trace data returned by GetData() resides. sl@0: @return The chunk. sl@0: */ sl@0: inline RChunk DataChunk(); sl@0: sl@0: /** sl@0: The operational mode for fast-trace. sl@0: @return The current operational mode. This is bitmask of values from TMode. sl@0: */ sl@0: IMPORT_C TUint Mode(); sl@0: sl@0: /** sl@0: Set the operational mode for fast-trace. sl@0: Calling this method, invalidates the trace data returned by the last call to GetData(). sl@0: @param aMode A bitmask of values from TMode. sl@0: */ sl@0: IMPORT_C void SetMode(TUint aMode); sl@0: sl@0: /** sl@0: Set the trace filter bit for the specified category. sl@0: @param aCategory A category value from BTrace::TCategories. sl@0: @param aValue The new filter value for the category. sl@0: 1 means traces of this category are output, 0 means they are suppressed. sl@0: Any other value will be ignored, and this method will just return the current sl@0: value of the filter. sl@0: @return The previous value of the filter for the category, 0 or 1. sl@0: Or KErrNotSupported if this category is not supported by this build of the kernel. sl@0: */ sl@0: IMPORT_C TInt SetFilter(TUint aCategory, TInt aValue); sl@0: sl@0: /** sl@0: Get the trace filter bit for the specified category. sl@0: @param aCategory A category value from enum BTrace::TCategory, sl@0: @return The value of the filter for the category, 0 or 1, sl@0: or KErrNotSupported if this category is not supported by this build of the kernel. sl@0: (1 means traces of this category are output, 0 means they are suppressed.) sl@0: */ sl@0: inline TInt Filter(TUint aCategory); sl@0: sl@0: /** sl@0: Set the trace secondary trace filter for the specified UID. sl@0: sl@0: This method can not be used to disable a UID key if SetFilter2(TInt aGlobalFilter) sl@0: has been used to set the filter to pass all traces. Such attempts result in a return sl@0: code of KErrNotSupported. sl@0: sl@0: @param aUid The UID to filter. sl@0: @param aValue The new filter value for the UID. sl@0: 1 means traces with this UID are output, 0 means they are suppressed. sl@0: Other values must not be used. sl@0: sl@0: @return The previous value of the filter for the UID, 0 or 1, if operation is successful. sl@0: Otherwise, a negative number representing a system wide error code. sl@0: (E.g. KErrNoMemory.) sl@0: */ sl@0: IMPORT_C TInt SetFilter2(TUint32 aUid, TBool aValue); sl@0: sl@0: /** sl@0: Set the secondary trace filter to include only the specified UIDs. sl@0: sl@0: @param aUids Pointer to array of UIDs. sl@0: @param aNumUids Number of UID values pointer to by \a aUid. sl@0: sl@0: @return KErrNone on success. sl@0: Otherwise, a negative number representing a system wide error code. sl@0: (E.g. KErrNoMemory.) sl@0: */ sl@0: IMPORT_C TInt SetFilter2(const TUint32* aUids, TInt aNumUids); sl@0: sl@0: /** sl@0: Set the secondary trace filter to pass or reject every trace. sl@0: sl@0: @param aGlobalFilter If 0, the secondary filter will reject sl@0: all traces; if 1, all traces are passed sl@0: by the filter. sl@0: Other values have no effect. sl@0: sl@0: @return The previous value of the global filter. sl@0: */ sl@0: IMPORT_C TInt SetFilter2(TInt aGlobalFilter); sl@0: sl@0: /** sl@0: Get the contents of the secondary trace filter. sl@0: sl@0: @param [out] aUids Pointer to array of UIDs contained in the secondary filter. sl@0: Ownership of this array is passed to the caller of this sl@0: function, which is then responsible for deleting it. sl@0: If filter is empty, \a aUid equals zero. sl@0: @param [out] aGlobalFilter Set to 1 if the secondary filter passes all traces. sl@0: Set to 0 if the secondary filter rejects all traces. sl@0: Set to -1 if the secondary filter operates by UIDs contained in traces. sl@0: sl@0: @return Number of UIDs in returned array, if operation is successful. sl@0: Otherwise, a negative number representing a system wide error code. sl@0: */ sl@0: IMPORT_C TInt Filter2(TUint32*& aUids, TInt& aGlobalFilter); sl@0: sl@0: /** sl@0: Get pointer to as much contiguous trace data as is available. sl@0: This data resides in the shared chunk DataChunk(). sl@0: The data returned will always be a whole number of trace records, i.e. trace records sl@0: will not be split between successive calls to this method. sl@0: Once the data is no loger required, DataUsed() must be called. sl@0: This method can be called repeatedly to get more trace data. E.g. sl@0: @code sl@0: RBTrace trace; sl@0: TInt error = trace.Open(); sl@0: if(error!=KErrNone) sl@0: return error; sl@0: const TInt KTraceDataBlockSize = 65536; // size of data we ideally want to process in one go sl@0: TUint8* data; sl@0: TInt size; sl@0: do sl@0: { sl@0: while((size=trace.GetData(data))!=0) sl@0: { sl@0: ProcessTheTraceData(data,size); sl@0: trace.DataUsed(); sl@0: } sl@0: TRequestStatus waitStatus; sl@0: trace.RequestData(waitStatus,KTraceDataBlockSize); sl@0: User::WaitForRequest(waitStatus); sl@0: error = waitStatus.Int(); sl@0: } sl@0: while(error==KErrNone); sl@0: trace.Close(); sl@0: return error; sl@0: @endcode sl@0: sl@0: @param aData Pointer to the first byte of trace data. sl@0: @return The number of bytes of trace data available at aData. sl@0: @see DataChunk(); sl@0: */ sl@0: IMPORT_C TInt GetData(TUint8*& aData); sl@0: sl@0: /** sl@0: Remove from the trace buffer all of the data returned by the last call to GetData(). sl@0: */ sl@0: IMPORT_C void DataUsed(); sl@0: sl@0: /** sl@0: Request notification when trace data becomes available. sl@0: Only one outstanding request may be present at any one time. sl@0: @param aStatus Request status to be complete with KErrNone once data becomes available. sl@0: @param aSize The minimum number of bytes of trace data required. sl@0: This is intended to improve performance by only signalling the client once sl@0: a suitably large amount of trace data is available. However, this request sl@0: may complete before this amount of trace data is available, therefore a sl@0: client must be able to handle this situation. sl@0: If aSize is zero or negative, then the request completes as soon as any trace sl@0: data is available. sl@0: @panic BTRACE 0 if a previous request is still pending sl@0: */ sl@0: IMPORT_C void RequestData(TRequestStatus& aStatus, TInt aSize); sl@0: sl@0: /** sl@0: Cancel any previous RequestData(), completing it with KErrCancel. sl@0: */ sl@0: IMPORT_C void CancelRequestData(); sl@0: sl@0: /** sl@0: @internalTechnology sl@0: */ sl@0: TBool SetSerialPortOutput(TBool aEnable); sl@0: sl@0: /** sl@0: Controls whether Timestamp2 field is added to trace record headers. sl@0: */ sl@0: IMPORT_C TBool SetTimestamp2Enabled(TBool aEnable); sl@0: sl@0: #endif sl@0: sl@0: /** sl@0: Enumeration of panic reasons for category 'BTRACE'. sl@0: */ sl@0: enum TPanic sl@0: { sl@0: ERequestAlreadyPending, /**< A call to RequestData() was made whist a request was already pending. */ sl@0: }; sl@0: private: sl@0: TInt OpenChunk(); sl@0: void CloseChunk(); sl@0: inline static const TDesC& Name(); sl@0: sl@0: enum TControl sl@0: { sl@0: EOpenBuffer, sl@0: EResizeBuffer, sl@0: ESetFilter, sl@0: ESetFilter2, sl@0: ESetFilter2Array, sl@0: ESetFilter2Global, sl@0: EGetFilter2Part1, sl@0: EGetFilter2Part2, sl@0: ERequestData, sl@0: ECancelRequestData, sl@0: ESetSerialPortOutput, sl@0: ESetTimestamp2Enabled, sl@0: }; sl@0: #ifndef __KERNEL_MODE__ sl@0: RChunk iDataChunk; sl@0: TBTraceBuffer* iBuffer; sl@0: TInt iLastGetDataSize; sl@0: TUint32 iSpare[4]; sl@0: #endif sl@0: friend class DBTraceChannel; sl@0: friend class DBTraceFactory; sl@0: friend class RBTraceAdapter; sl@0: }; sl@0: sl@0: #ifndef __KERNEL_MODE__ sl@0: sl@0: inline RChunk RBTrace::DataChunk() sl@0: { sl@0: return iDataChunk; sl@0: } sl@0: sl@0: inline TInt RBTrace::Filter(TUint aCategory) sl@0: { sl@0: return SetFilter(aCategory,-1); sl@0: } sl@0: sl@0: #endif // !__KERNEL_MODE__ sl@0: sl@0: inline const TDesC& RBTrace::Name() sl@0: { sl@0: _LIT(KBTraceName,"btrace"); sl@0: return KBTraceName; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class TBTraceBuffer sl@0: { sl@0: private: sl@0: TUint iStart; sl@0: TUint iEnd; sl@0: volatile TUint iHead; sl@0: volatile TUint iTail; sl@0: volatile TUint iWrap; sl@0: volatile TUint iGeneration; sl@0: volatile TUint iMode; sl@0: TUint iRecordOffsets; sl@0: TUint iCopyBuffer; sl@0: TUint iCopyBufferSize; sl@0: private: sl@0: TInt Data(TUint& aData, TUint& aTail); sl@0: TInt Adjust(TUint aTail, TInt aSize); sl@0: TInt CopyData(TUint aData, TUint aTail, TInt aSize); sl@0: TUint UpdateTail(TUint32 aOld, TUint32 aNew); sl@0: TInt GetData(TUint8*& aData); sl@0: sl@0: friend class RBTrace; sl@0: friend class TBTraceBufferK; sl@0: friend class RBTraceAdapter; sl@0: }; sl@0: sl@0: sl@0: sl@0: #endif