tracesrv/tracecore/btrace_handler/test/tracedataparser/src/tracedataparser.cpp
author hgs
Fri, 08 Oct 2010 14:56:39 +0300
changeset 56 aa2539c91954
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56
hgs
parents:
diff changeset
     1
// Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     2
// All rights reserved.
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     7
//
hgs
parents:
diff changeset
     8
// Initial Contributors:
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    10
//
hgs
parents:
diff changeset
    11
// Contributors:
hgs
parents:
diff changeset
    12
//
hgs
parents:
diff changeset
    13
// Description:
hgs
parents:
diff changeset
    14
// Trace Data parser
hgs
parents:
diff changeset
    15
//
hgs
parents:
diff changeset
    16
hgs
parents:
diff changeset
    17
#include <e32svr.h>
hgs
parents:
diff changeset
    18
#include <e32def.h>
hgs
parents:
diff changeset
    19
#include <e32def_private.h>
hgs
parents:
diff changeset
    20
#include <e32btrace.h>
hgs
parents:
diff changeset
    21
hgs
parents:
diff changeset
    22
#include "tracedataparser.h"
hgs
parents:
diff changeset
    23
#include "testdatawriternotifier.h"
hgs
parents:
diff changeset
    24
#include "tracecoreconstants.h"
hgs
parents:
diff changeset
    25
#include "d32tracebuffer.h"
hgs
parents:
diff changeset
    26
hgs
parents:
diff changeset
    27
hgs
parents:
diff changeset
    28
EXPORT_C TUint32 TTraceDataParser::Swap(TUint32 x)
hgs
parents:
diff changeset
    29
    {
hgs
parents:
diff changeset
    30
    return  (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24);
hgs
parents:
diff changeset
    31
    }
hgs
parents:
diff changeset
    32
hgs
parents:
diff changeset
    33
EXPORT_C TUint32 TTraceDataParser::ReadUint32FromBuf(TUint8*& aBuf, TBool aFromTestWriter)
hgs
parents:
diff changeset
    34
    {
hgs
parents:
diff changeset
    35
#ifdef __WINS__
hgs
parents:
diff changeset
    36
    aFromTestWriter = EFalse;
hgs
parents:
diff changeset
    37
#endif
hgs
parents:
diff changeset
    38
    // reads a 4 byte integer of expected endianess
hgs
parents:
diff changeset
    39
    TUint32 n;
hgs
parents:
diff changeset
    40
    if (!aFromTestWriter)
hgs
parents:
diff changeset
    41
        {
hgs
parents:
diff changeset
    42
        n = *(aBuf+3) + (*(aBuf+2) << 8) + (*(aBuf+1) << 16) + (*aBuf << 24);
hgs
parents:
diff changeset
    43
        }
hgs
parents:
diff changeset
    44
    else
hgs
parents:
diff changeset
    45
        {
hgs
parents:
diff changeset
    46
        // endianess order is reversed for TestWriter on hw
hgs
parents:
diff changeset
    47
        n = (*aBuf) + (*(aBuf+1) << 8) + (*(aBuf+2) << 16) + (*(aBuf+3) << 24);    
hgs
parents:
diff changeset
    48
        }
hgs
parents:
diff changeset
    49
    aBuf += sizeof(TUint32);
hgs
parents:
diff changeset
    50
    return n;
hgs
parents:
diff changeset
    51
    }
hgs
parents:
diff changeset
    52
hgs
parents:
diff changeset
    53
EXPORT_C TUint16 TTraceDataParser::ReadUint16FromBuf(TUint8*& aBuf)
hgs
parents:
diff changeset
    54
    {
hgs
parents:
diff changeset
    55
    // reads a 2 byte integer of expected endianess
hgs
parents:
diff changeset
    56
    TUint16 n = (*aBuf << 8)+ (*(aBuf+1));
hgs
parents:
diff changeset
    57
    aBuf += sizeof(TUint16);
hgs
parents:
diff changeset
    58
    return n;
hgs
parents:
diff changeset
    59
    }
hgs
parents:
diff changeset
    60
hgs
parents:
diff changeset
    61
TPtr8 TTraceDataParser::ReadTracePrintf(TUint8* aData, TInt aSize)
hgs
parents:
diff changeset
    62
    {
hgs
parents:
diff changeset
    63
    TPtr8 printfString(aData, aSize, aSize);
hgs
parents:
diff changeset
    64
    TInt endPosition = printfString.Locate(TChar(0));
hgs
parents:
diff changeset
    65
    if (endPosition >= 0)
hgs
parents:
diff changeset
    66
        {
hgs
parents:
diff changeset
    67
        printfString = printfString.Left(endPosition);
hgs
parents:
diff changeset
    68
        }
hgs
parents:
diff changeset
    69
    else
hgs
parents:
diff changeset
    70
        {
hgs
parents:
diff changeset
    71
        printfString.Trim();
hgs
parents:
diff changeset
    72
        }
hgs
parents:
diff changeset
    73
    return printfString;
hgs
parents:
diff changeset
    74
    }
hgs
parents:
diff changeset
    75
hgs
parents:
diff changeset
    76
TBool TTraceDataParser::StringsMatch(const TDesC8& aString1, const TDesC8& aString2)
hgs
parents:
diff changeset
    77
    {
hgs
parents:
diff changeset
    78
    TInt compareLength = (aString1.Length() > aString2.Length()) ? aString2.Length() : aString1.Length();
hgs
parents:
diff changeset
    79
    if ( (aString2.Left(compareLength).Compare(aString1) == 0) ||
hgs
parents:
diff changeset
    80
         (aString1.Left(compareLength).Compare(aString2) == 0) )
hgs
parents:
diff changeset
    81
        {
hgs
parents:
diff changeset
    82
        return ETrue;
hgs
parents:
diff changeset
    83
        }
hgs
parents:
diff changeset
    84
    return EFalse;
hgs
parents:
diff changeset
    85
    }
hgs
parents:
diff changeset
    86
hgs
parents:
diff changeset
    87
/**
hgs
parents:
diff changeset
    88
 * Function to string for a number
hgs
parents:
diff changeset
    89
 * @param aBuffer Trace data descriptor
hgs
parents:
diff changeset
    90
 * @param aFindStringPattern Pattern that indicates where in the string the number will be, using an asterisk
hgs
parents:
diff changeset
    91
 * @param aNumberFound If found, the number in the string
hgs
parents:
diff changeset
    92
 * @return Symbian error code
hgs
parents:
diff changeset
    93
 */
hgs
parents:
diff changeset
    94
TInt TTraceDataParser::ParseStringForNumber(const TDesC8& aBuffer, const TDesC8& aFindStringPattern, TInt& aNumberFound)
hgs
parents:
diff changeset
    95
    {
hgs
parents:
diff changeset
    96
    TInt err = KErrNotFound;
hgs
parents:
diff changeset
    97
    TInt posOfNum = aFindStringPattern.Locate('*');
hgs
parents:
diff changeset
    98
    TInt lengthOfNum = 1 + aBuffer.Length() - aFindStringPattern.Length();
hgs
parents:
diff changeset
    99
    if (posOfNum >= 0 && lengthOfNum >= 1)
hgs
parents:
diff changeset
   100
        {
hgs
parents:
diff changeset
   101
        TBuf<KMaxNumberBufferLength> numberBuffer;
hgs
parents:
diff changeset
   102
        numberBuffer.Copy(aBuffer.Mid(posOfNum, lengthOfNum));
hgs
parents:
diff changeset
   103
        TLex lex(numberBuffer);
hgs
parents:
diff changeset
   104
        err = lex.Val(aNumberFound);
hgs
parents:
diff changeset
   105
        }
hgs
parents:
diff changeset
   106
    return err;
hgs
parents:
diff changeset
   107
    }
hgs
parents:
diff changeset
   108
hgs
parents:
diff changeset
   109
/*
hgs
parents:
diff changeset
   110
 * Validate the trace data in buffer
hgs
parents:
diff changeset
   111
 *
hgs
parents:
diff changeset
   112
 * @param aBuffer the buffer containing the trace data
hgs
parents:
diff changeset
   113
 * @param aExpectedNum expected number of traces
hgs
parents:
diff changeset
   114
 * @param aComponentID component ID of traces
hgs
parents:
diff changeset
   115
 * @param aGroupID group ID of traces
hgs
parents:
diff changeset
   116
 * @param aData first expected trace data
hgs
parents:
diff changeset
   117
 * @param aTraceWord trace word of traces
hgs
parents:
diff changeset
   118
 * @param aIdentical indicates that the payload of each trace packet should be identical
hgs
parents:
diff changeset
   119
 * @param aBufferMode The mode of the trace buffer.. 0=straight, 1=circular.
hgs
parents:
diff changeset
   120
 * @param aOrdinalData indicates whether the payload data reflects its position in the stream of trace packets
hgs
parents:
diff changeset
   121
 * @param aNumTraces number of traces written to circular buffer
hgs
parents:
diff changeset
   122
 * @param aMaxTraces maximum number of traces circular buffer can hold
hgs
parents:
diff changeset
   123
 * @return Standard Symbian error code
hgs
parents:
diff changeset
   124
 */
hgs
parents:
diff changeset
   125
EXPORT_C TInt TTraceDataParser::ValidatePayload(TDesC8&         aBuffer,
hgs
parents:
diff changeset
   126
                                                TInt            aExpectedNum,
hgs
parents:
diff changeset
   127
                                                TComponentId    aComponentID, 
hgs
parents:
diff changeset
   128
                                                TGroupId        aGroupID, 
hgs
parents:
diff changeset
   129
                                                TUint32         aData, 
hgs
parents:
diff changeset
   130
                                                TUint32         aTraceWord,
hgs
parents:
diff changeset
   131
                                                TBool           aIdentical, 
hgs
parents:
diff changeset
   132
                                                TInt            aBufferMode, 
hgs
parents:
diff changeset
   133
                                                TBool           aOrdinalData, 
hgs
parents:
diff changeset
   134
                                                TInt            aNumTraces, 
hgs
parents:
diff changeset
   135
                                                TInt            aMaxTraces)
hgs
parents:
diff changeset
   136
    {
hgs
parents:
diff changeset
   137
    if ((aBuffer.Length() == 0) && (aExpectedNum <= 0))    // size is zero and there should be no traces
hgs
parents:
diff changeset
   138
        {
hgs
parents:
diff changeset
   139
        return KErrNone;
hgs
parents:
diff changeset
   140
        }
hgs
parents:
diff changeset
   141
    if ((aBuffer.Length() == 0) && (aExpectedNum > 0))     // size is zero and there should be traces
hgs
parents:
diff changeset
   142
        {
hgs
parents:
diff changeset
   143
        return KErrCorrupt;
hgs
parents:
diff changeset
   144
        }
hgs
parents:
diff changeset
   145
    if (aBuffer.Length() != 0 && (aExpectedNum <= 0))      // size is non-zero and there should be no traces
hgs
parents:
diff changeset
   146
        {
hgs
parents:
diff changeset
   147
        return KErrCorrupt;
hgs
parents:
diff changeset
   148
        }
hgs
parents:
diff changeset
   149
hgs
parents:
diff changeset
   150
    TUint32 lastData = aData;
hgs
parents:
diff changeset
   151
    TBool firstInStream = ETrue;
hgs
parents:
diff changeset
   152
hgs
parents:
diff changeset
   153
    // get the current position on the stream of traces so we can determine what the payload value should be.
hgs
parents:
diff changeset
   154
    TInt overwrites = 0;
hgs
parents:
diff changeset
   155
    if (aBufferMode == RTraceBuffer::EFreeRunning)
hgs
parents:
diff changeset
   156
        {
hgs
parents:
diff changeset
   157
        TInt overwrittenTraces = aNumTraces; // initialise to number of traces we wrote to the buffer for circular test
hgs
parents:
diff changeset
   158
        while (overwrittenTraces > aMaxTraces)
hgs
parents:
diff changeset
   159
            {
hgs
parents:
diff changeset
   160
            overwrittenTraces = overwrittenTraces - aMaxTraces; // aMaxTraces is the max the buffer can hold 
hgs
parents:
diff changeset
   161
            overwrites++;
hgs
parents:
diff changeset
   162
            }
hgs
parents:
diff changeset
   163
        lastData = (aMaxTraces * (overwrites - 1)) + overwrittenTraces + 1; // get where we are in the buffer
hgs
parents:
diff changeset
   164
        }
hgs
parents:
diff changeset
   165
hgs
parents:
diff changeset
   166
    TInt            numberOSTtraces = 0;
hgs
parents:
diff changeset
   167
    TUint8*         data            = (TUint8*) aBuffer.Ptr();
hgs
parents:
diff changeset
   168
    TUint8*         endOfData       = data + aBuffer.Size();    
hgs
parents:
diff changeset
   169
    TUint8          testGID         = aGroupID;
hgs
parents:
diff changeset
   170
    TUint32         testCID         = aComponentID;
hgs
parents:
diff changeset
   171
    TUint32         testTraceWord   = 0;
hgs
parents:
diff changeset
   172
hgs
parents:
diff changeset
   173
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
   174
hgs
parents:
diff changeset
   175
    // Loop through all traces
hgs
parents:
diff changeset
   176
    while (data < endOfData)
hgs
parents:
diff changeset
   177
        {
hgs
parents:
diff changeset
   178
        // Get trace info from header
hgs
parents:
diff changeset
   179
        TInt err = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
   180
        
hgs
parents:
diff changeset
   181
        if (err != KErrNone)
hgs
parents:
diff changeset
   182
            {
hgs
parents:
diff changeset
   183
            return err;
hgs
parents:
diff changeset
   184
            }
hgs
parents:
diff changeset
   185
hgs
parents:
diff changeset
   186
        //check the missing flag if we expect it
hgs
parents:
diff changeset
   187
        if ((firstInStream&&(overwrites>0)))
hgs
parents:
diff changeset
   188
            {
hgs
parents:
diff changeset
   189
            if(!(traceHeaderSettings.iHeaderFlags & BTrace::EMissingRecord))
hgs
parents:
diff changeset
   190
                {
hgs
parents:
diff changeset
   191
                return KErrCorrupt;
hgs
parents:
diff changeset
   192
                }
hgs
parents:
diff changeset
   193
            }
hgs
parents:
diff changeset
   194
hgs
parents:
diff changeset
   195
        if (!traceHeaderSettings.iPrintfTrace)
hgs
parents:
diff changeset
   196
            {
hgs
parents:
diff changeset
   197
            testTraceWord = ((TUint32) (testGID << GROUPIDSHIFT)) + 1;
hgs
parents:
diff changeset
   198
            
hgs
parents:
diff changeset
   199
            // check group ID
hgs
parents:
diff changeset
   200
            if (traceHeaderSettings.iCategory != testGID)
hgs
parents:
diff changeset
   201
                {
hgs
parents:
diff changeset
   202
                return KErrCorrupt;
hgs
parents:
diff changeset
   203
                }
hgs
parents:
diff changeset
   204
            // check component ID
hgs
parents:
diff changeset
   205
            if (traceHeaderSettings.iComponentID != testCID)
hgs
parents:
diff changeset
   206
                {
hgs
parents:
diff changeset
   207
                return KErrCorrupt;
hgs
parents:
diff changeset
   208
                }
hgs
parents:
diff changeset
   209
            // check trace word
hgs
parents:
diff changeset
   210
            if (traceHeaderSettings.iTraceWord != testTraceWord)
hgs
parents:
diff changeset
   211
                {
hgs
parents:
diff changeset
   212
                return KErrCorrupt;
hgs
parents:
diff changeset
   213
                }
hgs
parents:
diff changeset
   214
            
hgs
parents:
diff changeset
   215
            TBool lastTrace = EFalse;
hgs
parents:
diff changeset
   216
            if ( (traceHeaderSettings.iMultiPartType == BTrace::EMultipartLast) || (!traceHeaderSettings.iMultiPartType) )
hgs
parents:
diff changeset
   217
                {
hgs
parents:
diff changeset
   218
                lastTrace = ETrue;
hgs
parents:
diff changeset
   219
                }
hgs
parents:
diff changeset
   220
hgs
parents:
diff changeset
   221
            // check trace payload
hgs
parents:
diff changeset
   222
            for (TInt i=0; traceHeaderSettings.iLengthOfPayload>0; i++)
hgs
parents:
diff changeset
   223
                {
hgs
parents:
diff changeset
   224
                TUint32 param = Swap(ReadUint32FromBuf(data, traceHeaderSettings.iFromTestWriter));
hgs
parents:
diff changeset
   225
                // For circular case, we try to estimate to within +/- 2 where we are in payload
hgs
parents:
diff changeset
   226
                // for straight case we should get it exactly correct.
hgs
parents:
diff changeset
   227
                if ( ((param != lastData) && (aBufferMode == 0)) || 
hgs
parents:
diff changeset
   228
                      ( ((param > lastData + 2) || (param < lastData - 2)) && (aBufferMode == RTraceBuffer::EFreeRunning) ) )
hgs
parents:
diff changeset
   229
                    {
hgs
parents:
diff changeset
   230
                    return KErrCorrupt;
hgs
parents:
diff changeset
   231
                    }
hgs
parents:
diff changeset
   232
                lastData = param; // in case we weren't accurate in circular case.
hgs
parents:
diff changeset
   233
                traceHeaderSettings.iLengthOfPayload -= 4;
hgs
parents:
diff changeset
   234
                lastData++;
hgs
parents:
diff changeset
   235
                }
hgs
parents:
diff changeset
   236
            lastData = (!aOrdinalData)? aData : lastData;
hgs
parents:
diff changeset
   237
            if (!aOrdinalData)
hgs
parents:
diff changeset
   238
                {
hgs
parents:
diff changeset
   239
                lastData = (lastTrace || aIdentical) ? aData : lastData;
hgs
parents:
diff changeset
   240
                }
hgs
parents:
diff changeset
   241
hgs
parents:
diff changeset
   242
            if (traceHeaderSettings.iMultiPartType || aIdentical || aOrdinalData)
hgs
parents:
diff changeset
   243
                {
hgs
parents:
diff changeset
   244
                testGID = aGroupID;
hgs
parents:
diff changeset
   245
                testCID = aComponentID;
hgs
parents:
diff changeset
   246
                testTraceWord = aTraceWord;
hgs
parents:
diff changeset
   247
                }
hgs
parents:
diff changeset
   248
            else
hgs
parents:
diff changeset
   249
                {
hgs
parents:
diff changeset
   250
                testGID++;
hgs
parents:
diff changeset
   251
                testCID++;
hgs
parents:
diff changeset
   252
                testTraceWord += (1 << GROUPIDSHIFT);
hgs
parents:
diff changeset
   253
                }
hgs
parents:
diff changeset
   254
            numberOSTtraces++;
hgs
parents:
diff changeset
   255
            }
hgs
parents:
diff changeset
   256
        else
hgs
parents:
diff changeset
   257
            {
hgs
parents:
diff changeset
   258
            // Go to the next trace
hgs
parents:
diff changeset
   259
            data += traceHeaderSettings.iLengthOfPayload;
hgs
parents:
diff changeset
   260
            }
hgs
parents:
diff changeset
   261
        firstInStream = EFalse; //after this, it's defnitely not the first trace in the stream.
hgs
parents:
diff changeset
   262
        }
hgs
parents:
diff changeset
   263
hgs
parents:
diff changeset
   264
    // Check that we're getting the correct number of traces
hgs
parents:
diff changeset
   265
    //or approximate ammount (+/-1) for circular buffer because
hgs
parents:
diff changeset
   266
    //the arithmetic to overwrite traces sometimes also skips one
hgs
parents:
diff changeset
   267
    //extra trace
hgs
parents:
diff changeset
   268
hgs
parents:
diff changeset
   269
    if (numberOSTtraces != aExpectedNum)
hgs
parents:
diff changeset
   270
        {
hgs
parents:
diff changeset
   271
        if ((aBufferMode==RTraceBuffer::EFreeRunning)
hgs
parents:
diff changeset
   272
                &&((numberOSTtraces>=aExpectedNum-1)||(numberOSTtraces<=aExpectedNum+1)))
hgs
parents:
diff changeset
   273
            {
hgs
parents:
diff changeset
   274
            return KErrNone;
hgs
parents:
diff changeset
   275
            }
hgs
parents:
diff changeset
   276
        return KErrCorrupt;
hgs
parents:
diff changeset
   277
        }
hgs
parents:
diff changeset
   278
hgs
parents:
diff changeset
   279
    return KErrNone;
hgs
parents:
diff changeset
   280
    }
hgs
parents:
diff changeset
   281
hgs
parents:
diff changeset
   282
/*
hgs
parents:
diff changeset
   283
 * Validate the single trace data in buffer
hgs
parents:
diff changeset
   284
 * 
hgs
parents:
diff changeset
   285
 * @param aBuffer the buffer containing the trace data
hgs
parents:
diff changeset
   286
 * @param aTracePresent determines if trace data should be present or not
hgs
parents:
diff changeset
   287
 * @param aGroupID expected GID
hgs
parents:
diff changeset
   288
 * @param aComponentID expected CID
hgs
parents:
diff changeset
   289
 * @param aData expected trace data
hgs
parents:
diff changeset
   290
 * @param aPrintfTrace determines if trace data should be printf data or not
hgs
parents:
diff changeset
   291
 * @param aMissingTrace determines if trace data should indicate missing data or not
hgs
parents:
diff changeset
   292
 * @param aExpectedPrintfTrace expected printf trace data
hgs
parents:
diff changeset
   293
 * @return Standard Symbian error code
hgs
parents:
diff changeset
   294
 */
hgs
parents:
diff changeset
   295
EXPORT_C TInt TTraceDataParser::ValidatePayload(TDesC8&        aBuffer, 
hgs
parents:
diff changeset
   296
                                                TBool          aTracePresent, 
hgs
parents:
diff changeset
   297
                                                TGroupId       aGroupID, 
hgs
parents:
diff changeset
   298
                                                TComponentId   aComponentID, 
hgs
parents:
diff changeset
   299
                                                TUint32        aData,
hgs
parents:
diff changeset
   300
                                                TBool          aPrintfTrace,
hgs
parents:
diff changeset
   301
                                                TBool          aMissingTrace,
hgs
parents:
diff changeset
   302
                                                TDesC8*        aExpectedPrintfTrace)
hgs
parents:
diff changeset
   303
    {
hgs
parents:
diff changeset
   304
    if ((aBuffer.Length() == 0) && (!aTracePresent))    // size is zero and there should be no traces
hgs
parents:
diff changeset
   305
        {
hgs
parents:
diff changeset
   306
        return KErrNone;
hgs
parents:
diff changeset
   307
        }
hgs
parents:
diff changeset
   308
    if ((aBuffer.Length() == 0) && (aTracePresent))     // size is zero and there should be traces
hgs
parents:
diff changeset
   309
        {
hgs
parents:
diff changeset
   310
        return KErrCorrupt;
hgs
parents:
diff changeset
   311
        }
hgs
parents:
diff changeset
   312
    if (aBuffer.Length() != 0 && (!aTracePresent))      // size is non-zero and there should be no traces
hgs
parents:
diff changeset
   313
        {
hgs
parents:
diff changeset
   314
        return KErrCorrupt;
hgs
parents:
diff changeset
   315
        }
hgs
parents:
diff changeset
   316
hgs
parents:
diff changeset
   317
    TUint8*         data            = (TUint8*) aBuffer.Ptr();
hgs
parents:
diff changeset
   318
    TUint8*         endOfData       = data + aBuffer.Size();    
hgs
parents:
diff changeset
   319
hgs
parents:
diff changeset
   320
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
   321
hgs
parents:
diff changeset
   322
    // Get trace info from header
hgs
parents:
diff changeset
   323
    TInt err = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
   324
    
hgs
parents:
diff changeset
   325
    if (err != KErrNone)
hgs
parents:
diff changeset
   326
        {
hgs
parents:
diff changeset
   327
        return err;
hgs
parents:
diff changeset
   328
        }
hgs
parents:
diff changeset
   329
hgs
parents:
diff changeset
   330
    // check trace type
hgs
parents:
diff changeset
   331
    if (traceHeaderSettings.iPrintfTrace != aPrintfTrace)
hgs
parents:
diff changeset
   332
        {
hgs
parents:
diff changeset
   333
        return KErrCorrupt;
hgs
parents:
diff changeset
   334
        }
hgs
parents:
diff changeset
   335
hgs
parents:
diff changeset
   336
    if (!traceHeaderSettings.iPrintfTrace)
hgs
parents:
diff changeset
   337
        {
hgs
parents:
diff changeset
   338
        TUint32 testTraceWord = ((TUint32) (aGroupID << GROUPIDSHIFT)) + 1;
hgs
parents:
diff changeset
   339
        
hgs
parents:
diff changeset
   340
        // check group ID
hgs
parents:
diff changeset
   341
        if (traceHeaderSettings.iCategory != aGroupID)
hgs
parents:
diff changeset
   342
            {
hgs
parents:
diff changeset
   343
            return KErrCorrupt;
hgs
parents:
diff changeset
   344
            }
hgs
parents:
diff changeset
   345
        // check component ID
hgs
parents:
diff changeset
   346
        if (traceHeaderSettings.iComponentID != aComponentID)
hgs
parents:
diff changeset
   347
            {
hgs
parents:
diff changeset
   348
            return KErrCorrupt;
hgs
parents:
diff changeset
   349
            }
hgs
parents:
diff changeset
   350
        // check trace word
hgs
parents:
diff changeset
   351
        if (traceHeaderSettings.iTraceWord != testTraceWord)
hgs
parents:
diff changeset
   352
            {
hgs
parents:
diff changeset
   353
            return KErrCorrupt;
hgs
parents:
diff changeset
   354
            }
hgs
parents:
diff changeset
   355
        
hgs
parents:
diff changeset
   356
        if (aMissingTrace)
hgs
parents:
diff changeset
   357
            {
hgs
parents:
diff changeset
   358
            // check missing flag
hgs
parents:
diff changeset
   359
            if (!(traceHeaderSettings.iHeaderFlags & BTrace::EMissingRecord))
hgs
parents:
diff changeset
   360
                {
hgs
parents:
diff changeset
   361
                return KErrCorrupt;
hgs
parents:
diff changeset
   362
                }
hgs
parents:
diff changeset
   363
            }
hgs
parents:
diff changeset
   364
        
hgs
parents:
diff changeset
   365
        TInt i = 0;
hgs
parents:
diff changeset
   366
        while (data < endOfData)
hgs
parents:
diff changeset
   367
            {
hgs
parents:
diff changeset
   368
            TUint32 param = Swap(ReadUint32FromBuf(data, traceHeaderSettings.iFromTestWriter));
hgs
parents:
diff changeset
   369
            if (param != aData + i)
hgs
parents:
diff changeset
   370
                {
hgs
parents:
diff changeset
   371
                return KErrCorrupt;
hgs
parents:
diff changeset
   372
                }
hgs
parents:
diff changeset
   373
            i++;
hgs
parents:
diff changeset
   374
            }
hgs
parents:
diff changeset
   375
        }
hgs
parents:
diff changeset
   376
    else if (!aExpectedPrintfTrace)
hgs
parents:
diff changeset
   377
        {
hgs
parents:
diff changeset
   378
        return KErrArgument;
hgs
parents:
diff changeset
   379
        }
hgs
parents:
diff changeset
   380
    else
hgs
parents:
diff changeset
   381
        {
hgs
parents:
diff changeset
   382
        TBuf8<KExpectedPrintfMaxLength> expectedPrintf;
hgs
parents:
diff changeset
   383
        
hgs
parents:
diff changeset
   384
        // In the case of an expected dropped trace, we only check for "* Dropped Trace" because
hgs
parents:
diff changeset
   385
        // the test writer has completed the request for data when it writes that bit first (right 
hgs
parents:
diff changeset
   386
        // before the next trace), and when it goes to write the actual trace, it doesn't.
hgs
parents:
diff changeset
   387
        // If we change this, the "* Dropped Trace" will be overwritten by the actual trace before
hgs
parents:
diff changeset
   388
        // the test can check it, since the test writer doesn't buffer trace data.
hgs
parents:
diff changeset
   389
        if (aMissingTrace)
hgs
parents:
diff changeset
   390
            {
hgs
parents:
diff changeset
   391
            // check that "* Dropped Trace" is in the buffer
hgs
parents:
diff changeset
   392
            expectedPrintf = KDroppedTrace;
hgs
parents:
diff changeset
   393
            }
hgs
parents:
diff changeset
   394
        else
hgs
parents:
diff changeset
   395
            {
hgs
parents:
diff changeset
   396
            // check that "Test Printf Trace" is in the buffer"
hgs
parents:
diff changeset
   397
            expectedPrintf = *aExpectedPrintfTrace;
hgs
parents:
diff changeset
   398
            }
hgs
parents:
diff changeset
   399
        
hgs
parents:
diff changeset
   400
        expectedPrintf.Append(TChar(0)); // printf handler appends null at the end.
hgs
parents:
diff changeset
   401
hgs
parents:
diff changeset
   402
        TPtrC8 actualprintf(data, traceHeaderSettings.iLengthOfPayload);
hgs
parents:
diff changeset
   403
hgs
parents:
diff changeset
   404
        // Need to fix endianess for hw
hgs
parents:
diff changeset
   405
#ifndef __WINS__
hgs
parents:
diff changeset
   406
        TInt bufpos = 0;
hgs
parents:
diff changeset
   407
        while (bufpos < (actualprintf.Length()-4))
hgs
parents:
diff changeset
   408
            {
hgs
parents:
diff changeset
   409
            // reads a 4 byte integer of expected endianess
hgs
parents:
diff changeset
   410
            TUint32 n = actualprintf[bufpos] + (actualprintf[bufpos+1] << 8) + (actualprintf[bufpos+2] << 16) + (actualprintf[bufpos+3] << 24);
hgs
parents:
diff changeset
   411
            bufpos += sizeof(TUint32);
hgs
parents:
diff changeset
   412
            TUint32 tempData = Swap(n);
hgs
parents:
diff changeset
   413
            memcpy((TAny*)(actualprintf.Ptr()+bufpos-4),(TAny*)&tempData, sizeof(TUint32));
hgs
parents:
diff changeset
   414
            }        
hgs
parents:
diff changeset
   415
#endif //__WINS__
hgs
parents:
diff changeset
   416
        
hgs
parents:
diff changeset
   417
        if (expectedPrintf.Compare(actualprintf) != 0)
hgs
parents:
diff changeset
   418
            {
hgs
parents:
diff changeset
   419
            return KErrCorrupt;
hgs
parents:
diff changeset
   420
            }
hgs
parents:
diff changeset
   421
hgs
parents:
diff changeset
   422
        // Check if there is another trace to follow
hgs
parents:
diff changeset
   423
        data += traceHeaderSettings.iLengthOfPayload;
hgs
parents:
diff changeset
   424
        if (data != endOfData)
hgs
parents:
diff changeset
   425
            {
hgs
parents:
diff changeset
   426
            TPtrC8 buffer(data, endOfData - data);
hgs
parents:
diff changeset
   427
            
hgs
parents:
diff changeset
   428
            return ValidatePayload(buffer, 
hgs
parents:
diff changeset
   429
                                   aTracePresent, 
hgs
parents:
diff changeset
   430
                                   aGroupID, 
hgs
parents:
diff changeset
   431
                                   aComponentID, 
hgs
parents:
diff changeset
   432
                                   aData,
hgs
parents:
diff changeset
   433
                                   aPrintfTrace,
hgs
parents:
diff changeset
   434
                                   EFalse,
hgs
parents:
diff changeset
   435
                                   aExpectedPrintfTrace);
hgs
parents:
diff changeset
   436
            }
hgs
parents:
diff changeset
   437
        }    
hgs
parents:
diff changeset
   438
    return KErrNone;
hgs
parents:
diff changeset
   439
    }
hgs
parents:
diff changeset
   440
hgs
parents:
diff changeset
   441
/*
hgs
parents:
diff changeset
   442
 * Verify the priming data contains all the expected values
hgs
parents:
diff changeset
   443
 *
hgs
parents:
diff changeset
   444
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
   445
 * @param aSize Size of the trace buffer
hgs
parents:
diff changeset
   446
 * @param aCategory BTrace category of the trace data
hgs
parents:
diff changeset
   447
 * @param aSubCategory BTrace subcategory of the trace data
hgs
parents:
diff changeset
   448
 * @param aElementsFound Parameter to hold current state of expected data found so far
hgs
parents:
diff changeset
   449
 * @param aVerificationData1 Optional input value - used differently for different categories
hgs
parents:
diff changeset
   450
 * @param aVerificationData2 Optional input value - used differently for different categories
hgs
parents:
diff changeset
   451
 * @return Standard Symbian error code
hgs
parents:
diff changeset
   452
 */
hgs
parents:
diff changeset
   453
TInt TTraceDataParser::VerifyPrimingData(TUint8* aBuffer, 
hgs
parents:
diff changeset
   454
                                         TInt    aSize, 
hgs
parents:
diff changeset
   455
                                         TUint8  aCategory, 
hgs
parents:
diff changeset
   456
                                         TUint8  aSubCategory, 
hgs
parents:
diff changeset
   457
                                         TInt&   aElementsFound,
hgs
parents:
diff changeset
   458
                                         TBool   aFromTestWriter, 
hgs
parents:
diff changeset
   459
                                         TUint32 aVerificationData1, 
hgs
parents:
diff changeset
   460
                                         TUint32 aVerificationData2)
hgs
parents:
diff changeset
   461
    {
hgs
parents:
diff changeset
   462
    TInt err = KErrNotSupported;
hgs
parents:
diff changeset
   463
    switch(aCategory)
hgs
parents:
diff changeset
   464
        {
hgs
parents:
diff changeset
   465
        case BTrace::EThreadIdentification:
hgs
parents:
diff changeset
   466
            err = VerifyThreadPrimingData(aBuffer, aSize, aSubCategory, aElementsFound, aFromTestWriter, aVerificationData1, aVerificationData2);
hgs
parents:
diff changeset
   467
            break;
hgs
parents:
diff changeset
   468
        case BTrace::EFastMutex:
hgs
parents:
diff changeset
   469
            err = VerifyFastMutexPrimingData(aBuffer, aSize, aSubCategory, aElementsFound, aFromTestWriter);
hgs
parents:
diff changeset
   470
            break;
hgs
parents:
diff changeset
   471
        case BTrace::ECodeSegs:
hgs
parents:
diff changeset
   472
            err = VerifyCodeSegsPrimingData(aBuffer, aSize, aSubCategory, aElementsFound, aFromTestWriter, aVerificationData1, aVerificationData2);
hgs
parents:
diff changeset
   473
            break;
hgs
parents:
diff changeset
   474
        default:
hgs
parents:
diff changeset
   475
            break;
hgs
parents:
diff changeset
   476
        }
hgs
parents:
diff changeset
   477
    return err;    
hgs
parents:
diff changeset
   478
    }
hgs
parents:
diff changeset
   479
hgs
parents:
diff changeset
   480
/*
hgs
parents:
diff changeset
   481
 * Verify the EThreadIdentification priming data contains all the expected values
hgs
parents:
diff changeset
   482
 *
hgs
parents:
diff changeset
   483
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
   484
 * @param aSize Size of the trace buffer
hgs
parents:
diff changeset
   485
 * @param aSubCategory BTrace subcategory of the trace data
hgs
parents:
diff changeset
   486
 * @param aElementsFound Parameter to hold current state of expected data found so far
hgs
parents:
diff changeset
   487
 * @param aThreadAddr The address of the thread to search for
hgs
parents:
diff changeset
   488
 * @param aProcessAddr The address of the process to search for
hgs
parents:
diff changeset
   489
 * @return Standard Symbian error code
hgs
parents:
diff changeset
   490
 */
hgs
parents:
diff changeset
   491
TInt TTraceDataParser::VerifyThreadPrimingData(TUint8* aBuffer, 
hgs
parents:
diff changeset
   492
                                               TInt    aSize, 
hgs
parents:
diff changeset
   493
                                               TUint8  aSubCategory, 
hgs
parents:
diff changeset
   494
                                               TInt&   aElementsFound,
hgs
parents:
diff changeset
   495
                                               TBool   aFromTestWriter, 
hgs
parents:
diff changeset
   496
                                               TUint32 aThreadAddr, 
hgs
parents:
diff changeset
   497
                                               TUint32 aProcessAddr)
hgs
parents:
diff changeset
   498
    {
hgs
parents:
diff changeset
   499
    RThread currentThread;    
hgs
parents:
diff changeset
   500
    RProcess currentProcess;
hgs
parents:
diff changeset
   501
hgs
parents:
diff changeset
   502
    TUint32 tempThreadAddr;
hgs
parents:
diff changeset
   503
    TUint32 tempProcessAddr;
hgs
parents:
diff changeset
   504
    
hgs
parents:
diff changeset
   505
    switch(aSubCategory)
hgs
parents:
diff changeset
   506
        {
hgs
parents:
diff changeset
   507
        case BTrace::EProcessCreate:
hgs
parents:
diff changeset
   508
            {
hgs
parents:
diff changeset
   509
            tempProcessAddr = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   510
            if (tempProcessAddr == aProcessAddr)
hgs
parents:
diff changeset
   511
                {
hgs
parents:
diff changeset
   512
                aElementsFound |= 0x000000ff;
hgs
parents:
diff changeset
   513
                }
hgs
parents:
diff changeset
   514
            }
hgs
parents:
diff changeset
   515
            break;
hgs
parents:
diff changeset
   516
            
hgs
parents:
diff changeset
   517
        case BTrace::EProcessName:
hgs
parents:
diff changeset
   518
            {
hgs
parents:
diff changeset
   519
            tempThreadAddr = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   520
            tempProcessAddr = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   521
            if ( (tempThreadAddr == aThreadAddr) && (tempProcessAddr == aProcessAddr) )
hgs
parents:
diff changeset
   522
                {
hgs
parents:
diff changeset
   523
                TBuf8<KMaxName> currentProcessName;
hgs
parents:
diff changeset
   524
                currentProcessName.Copy(currentProcess.Name());
hgs
parents:
diff changeset
   525
                TPtr8 processName(aBuffer,(aSize-8),(aSize-8)); //should be name of the process
hgs
parents:
diff changeset
   526
                processName.Trim();
hgs
parents:
diff changeset
   527
                if (StringsMatch(currentProcessName, processName))
hgs
parents:
diff changeset
   528
                    {
hgs
parents:
diff changeset
   529
                    aElementsFound |= 0x0000ff00;
hgs
parents:
diff changeset
   530
                    }
hgs
parents:
diff changeset
   531
                }
hgs
parents:
diff changeset
   532
            }
hgs
parents:
diff changeset
   533
            break;
hgs
parents:
diff changeset
   534
        
hgs
parents:
diff changeset
   535
        case BTrace::EThreadName:
hgs
parents:
diff changeset
   536
            {
hgs
parents:
diff changeset
   537
            tempThreadAddr = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   538
            tempProcessAddr = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   539
            if ( (tempThreadAddr == aThreadAddr) && (tempProcessAddr == aProcessAddr) )
hgs
parents:
diff changeset
   540
                {
hgs
parents:
diff changeset
   541
                TBuf8<KMaxName> currentThreadName;
hgs
parents:
diff changeset
   542
                currentThreadName.Copy(currentThread.Name());
hgs
parents:
diff changeset
   543
                TPtr8 threadName(aBuffer,(aSize-8),(aSize-8)); //should be name of the thread
hgs
parents:
diff changeset
   544
                threadName.Trim();
hgs
parents:
diff changeset
   545
                if (StringsMatch(currentThreadName, threadName))
hgs
parents:
diff changeset
   546
                    {
hgs
parents:
diff changeset
   547
                    aElementsFound |= 0x00ff0000;
hgs
parents:
diff changeset
   548
                    }
hgs
parents:
diff changeset
   549
                }
hgs
parents:
diff changeset
   550
            }
hgs
parents:
diff changeset
   551
            break;
hgs
parents:
diff changeset
   552
            
hgs
parents:
diff changeset
   553
        case BTrace::EThreadId:
hgs
parents:
diff changeset
   554
            {
hgs
parents:
diff changeset
   555
            tempThreadAddr = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   556
            tempProcessAddr = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   557
            if ( (tempThreadAddr == aThreadAddr) && (tempProcessAddr == aProcessAddr) )
hgs
parents:
diff changeset
   558
                {
hgs
parents:
diff changeset
   559
                TThreadId threadId = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   560
                if (currentThread.Id() == threadId)
hgs
parents:
diff changeset
   561
                    {
hgs
parents:
diff changeset
   562
                    aElementsFound |= 0xff000000;
hgs
parents:
diff changeset
   563
                    }
hgs
parents:
diff changeset
   564
                }
hgs
parents:
diff changeset
   565
            }
hgs
parents:
diff changeset
   566
            break; 
hgs
parents:
diff changeset
   567
            
hgs
parents:
diff changeset
   568
        default:
hgs
parents:
diff changeset
   569
            break;
hgs
parents:
diff changeset
   570
        }
hgs
parents:
diff changeset
   571
    
hgs
parents:
diff changeset
   572
    TInt err = KErrNotFound;
hgs
parents:
diff changeset
   573
    if (aElementsFound == 0xffffffff)
hgs
parents:
diff changeset
   574
        {
hgs
parents:
diff changeset
   575
        err = KErrNone;
hgs
parents:
diff changeset
   576
        }
hgs
parents:
diff changeset
   577
    return err;
hgs
parents:
diff changeset
   578
    }
hgs
parents:
diff changeset
   579
hgs
parents:
diff changeset
   580
/*
hgs
parents:
diff changeset
   581
 * Verify the EFastMutex priming data contains all the expected values
hgs
parents:
diff changeset
   582
 *
hgs
parents:
diff changeset
   583
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
   584
 * @param aSize Size of the trace buffer
hgs
parents:
diff changeset
   585
 * @param aSubCategory BTrace subcategory of the trace data
hgs
parents:
diff changeset
   586
 * @param aElementsFound Parameter to hold current state of expected data found so far
hgs
parents:
diff changeset
   587
 * @return Standard Symbian error code
hgs
parents:
diff changeset
   588
 */
hgs
parents:
diff changeset
   589
TInt TTraceDataParser::VerifyFastMutexPrimingData(TUint8* aBuffer, 
hgs
parents:
diff changeset
   590
                                                  TInt    aSize, 
hgs
parents:
diff changeset
   591
                                                  TUint8  aSubCategory, 
hgs
parents:
diff changeset
   592
                                                  TInt&   aElementsFound,
hgs
parents:
diff changeset
   593
                                                  TBool   aFromTestWriter)
hgs
parents:
diff changeset
   594
    {
hgs
parents:
diff changeset
   595
    if (aSubCategory == BTrace::EFastMutexName)
hgs
parents:
diff changeset
   596
        {
hgs
parents:
diff changeset
   597
        TUint32 fastMutexId = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   598
        TUint32 unspecified = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   599
        if (fastMutexId && !unspecified)
hgs
parents:
diff changeset
   600
            {
hgs
parents:
diff changeset
   601
            TPtr8 fastMutexName(aBuffer,(aSize-8),(aSize-8)); //should be name of the fast mutex
hgs
parents:
diff changeset
   602
            fastMutexName.Trim();
hgs
parents:
diff changeset
   603
            if (StringsMatch(KFastMutexNameSystemLock(), fastMutexName))
hgs
parents:
diff changeset
   604
                {
hgs
parents:
diff changeset
   605
                aElementsFound |= 0x000000ff;
hgs
parents:
diff changeset
   606
                }
hgs
parents:
diff changeset
   607
            else if (StringsMatch(KFastMutexNameMsgLock(), fastMutexName))
hgs
parents:
diff changeset
   608
                {
hgs
parents:
diff changeset
   609
                aElementsFound |= 0x0000ff00;
hgs
parents:
diff changeset
   610
                }
hgs
parents:
diff changeset
   611
            else if (StringsMatch(KFastMutexNameObjLock(), fastMutexName))
hgs
parents:
diff changeset
   612
                {
hgs
parents:
diff changeset
   613
                aElementsFound |= 0x00ff0000;
hgs
parents:
diff changeset
   614
                }
hgs
parents:
diff changeset
   615
            else if (StringsMatch(KFastMutexNameLogonLock(), fastMutexName))
hgs
parents:
diff changeset
   616
                {
hgs
parents:
diff changeset
   617
                aElementsFound |= 0xff000000;
hgs
parents:
diff changeset
   618
                }
hgs
parents:
diff changeset
   619
            }
hgs
parents:
diff changeset
   620
        }
hgs
parents:
diff changeset
   621
    
hgs
parents:
diff changeset
   622
    TInt err = KErrNotFound;
hgs
parents:
diff changeset
   623
    if (aElementsFound == 0xffffffff)
hgs
parents:
diff changeset
   624
        {
hgs
parents:
diff changeset
   625
        err = KErrNone;
hgs
parents:
diff changeset
   626
        }
hgs
parents:
diff changeset
   627
    return err;
hgs
parents:
diff changeset
   628
    }
hgs
parents:
diff changeset
   629
hgs
parents:
diff changeset
   630
/*
hgs
parents:
diff changeset
   631
 * Verify the ECodeSegs priming data contains all the expected values
hgs
parents:
diff changeset
   632
 *
hgs
parents:
diff changeset
   633
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
   634
 * @param aSize Size of the trace buffer
hgs
parents:
diff changeset
   635
 * @param aSubCategory BTrace subcategory of the trace data
hgs
parents:
diff changeset
   636
 * @param aElementsFound Parameter to hold current state of expected data found so far
hgs
parents:
diff changeset
   637
 * @param aSegAddr1 The address of the first code seg to search for
hgs
parents:
diff changeset
   638
 * @param aSegAddr2 The address of the second code seg to search for
hgs
parents:
diff changeset
   639
 * @return Standard Symbian error code
hgs
parents:
diff changeset
   640
 */
hgs
parents:
diff changeset
   641
TInt TTraceDataParser::VerifyCodeSegsPrimingData(TUint8* aBuffer, 
hgs
parents:
diff changeset
   642
                                                 TInt    aSize, 
hgs
parents:
diff changeset
   643
                                                 TUint8  aSubCategory, 
hgs
parents:
diff changeset
   644
                                                 TInt&   aElementsFound,
hgs
parents:
diff changeset
   645
                                                 TBool   aFromTestWriter, 
hgs
parents:
diff changeset
   646
                                                 TUint32 aSegAddr1, 
hgs
parents:
diff changeset
   647
                                                 TUint32 aSegAddr2)
hgs
parents:
diff changeset
   648
    {
hgs
parents:
diff changeset
   649
    TUint32 codeSegAddr;
hgs
parents:
diff changeset
   650
    if (aSubCategory == BTrace::ECodeSegCreated)
hgs
parents:
diff changeset
   651
        {
hgs
parents:
diff changeset
   652
        codeSegAddr = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   653
        if (codeSegAddr == aSegAddr1 || codeSegAddr == aSegAddr2)
hgs
parents:
diff changeset
   654
            {
hgs
parents:
diff changeset
   655
            TPtr8 codeSegName(aBuffer,(aSize-4),(aSize-4)); //should be name of the code seg
hgs
parents:
diff changeset
   656
            codeSegName.Trim();
hgs
parents:
diff changeset
   657
            if (codeSegAddr == aSegAddr1 && StringsMatch(KCodeSegsName1(), codeSegName))
hgs
parents:
diff changeset
   658
                {
hgs
parents:
diff changeset
   659
                aElementsFound |= 0x000000ff;
hgs
parents:
diff changeset
   660
                }
hgs
parents:
diff changeset
   661
            else if (codeSegAddr == aSegAddr2 && StringsMatch(KCodeSegsName2(), codeSegName))
hgs
parents:
diff changeset
   662
                {
hgs
parents:
diff changeset
   663
                aElementsFound |= 0x0000ff00;
hgs
parents:
diff changeset
   664
                }
hgs
parents:
diff changeset
   665
            }
hgs
parents:
diff changeset
   666
        }
hgs
parents:
diff changeset
   667
    else if (aSubCategory == BTrace::ECodeSegInfo)
hgs
parents:
diff changeset
   668
        {
hgs
parents:
diff changeset
   669
        codeSegAddr = Swap(ReadUint32FromBuf(aBuffer, aFromTestWriter));
hgs
parents:
diff changeset
   670
        if (codeSegAddr == aSegAddr1)
hgs
parents:
diff changeset
   671
            {
hgs
parents:
diff changeset
   672
            aElementsFound |= 0x00ff0000;
hgs
parents:
diff changeset
   673
            }
hgs
parents:
diff changeset
   674
        else if (codeSegAddr == aSegAddr2)
hgs
parents:
diff changeset
   675
            {
hgs
parents:
diff changeset
   676
            aElementsFound |= 0xff000000;
hgs
parents:
diff changeset
   677
            }
hgs
parents:
diff changeset
   678
        }
hgs
parents:
diff changeset
   679
    
hgs
parents:
diff changeset
   680
    TInt err = KErrNotFound;
hgs
parents:
diff changeset
   681
    if (aElementsFound == 0xffffffff)
hgs
parents:
diff changeset
   682
        {
hgs
parents:
diff changeset
   683
        err = KErrNone;
hgs
parents:
diff changeset
   684
        }
hgs
parents:
diff changeset
   685
    return err;
hgs
parents:
diff changeset
   686
    }
hgs
parents:
diff changeset
   687
hgs
parents:
diff changeset
   688
/*
hgs
parents:
diff changeset
   689
 * Work out if a trace point is potentially kernel priming data based on category and subcategory
hgs
parents:
diff changeset
   690
 *
hgs
parents:
diff changeset
   691
 * @param aCategory BTrace category of the trace data
hgs
parents:
diff changeset
   692
 * @param aSubCategory BTrace subcategory of the trace data
hgs
parents:
diff changeset
   693
 * @param aIsPotentialPrimingTrace Output value set if there is no error
hgs
parents:
diff changeset
   694
 * @return Standard Symbian error code
hgs
parents:
diff changeset
   695
 */
hgs
parents:
diff changeset
   696
TBool TTraceDataParser::IsPotentialPrimingTrace(TUint8 aCategory, TUint8 aSubCategory, TBool& aIsPotentialPrimingTrace)
hgs
parents:
diff changeset
   697
    {
hgs
parents:
diff changeset
   698
    TInt err = KErrNone;
hgs
parents:
diff changeset
   699
    
hgs
parents:
diff changeset
   700
    switch(aCategory)
hgs
parents:
diff changeset
   701
        {
hgs
parents:
diff changeset
   702
        case BTrace::EThreadIdentification:
hgs
parents:
diff changeset
   703
            {
hgs
parents:
diff changeset
   704
            switch(aSubCategory)
hgs
parents:
diff changeset
   705
                {
hgs
parents:
diff changeset
   706
                case BTrace::EProcessCreate:
hgs
parents:
diff changeset
   707
                case BTrace::EProcessName:
hgs
parents:
diff changeset
   708
                case BTrace::EThreadName:
hgs
parents:
diff changeset
   709
                case BTrace::EThreadId:
hgs
parents:
diff changeset
   710
                    aIsPotentialPrimingTrace = ETrue;
hgs
parents:
diff changeset
   711
                    break;
hgs
parents:
diff changeset
   712
                default:
hgs
parents:
diff changeset
   713
                    aIsPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   714
                    break;
hgs
parents:
diff changeset
   715
                }
hgs
parents:
diff changeset
   716
            }
hgs
parents:
diff changeset
   717
            break;
hgs
parents:
diff changeset
   718
        case BTrace::ECpuUsage:
hgs
parents:
diff changeset
   719
            {
hgs
parents:
diff changeset
   720
            switch(aSubCategory)
hgs
parents:
diff changeset
   721
                {
hgs
parents:
diff changeset
   722
                case BTrace::ENewThreadContext:
hgs
parents:
diff changeset
   723
                    aIsPotentialPrimingTrace = ETrue;
hgs
parents:
diff changeset
   724
                    break;
hgs
parents:
diff changeset
   725
                default:
hgs
parents:
diff changeset
   726
                    aIsPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   727
                    break;
hgs
parents:
diff changeset
   728
                }
hgs
parents:
diff changeset
   729
            }
hgs
parents:
diff changeset
   730
            break;
hgs
parents:
diff changeset
   731
        case BTrace::EChunks:
hgs
parents:
diff changeset
   732
            {
hgs
parents:
diff changeset
   733
            switch(aSubCategory)
hgs
parents:
diff changeset
   734
                {
hgs
parents:
diff changeset
   735
                case BTrace::EChunkCreated:
hgs
parents:
diff changeset
   736
                case BTrace::EChunkOwner:
hgs
parents:
diff changeset
   737
                case BTrace::EChunkInfo:
hgs
parents:
diff changeset
   738
                    aIsPotentialPrimingTrace = ETrue;
hgs
parents:
diff changeset
   739
                    break;
hgs
parents:
diff changeset
   740
                default:
hgs
parents:
diff changeset
   741
                    aIsPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   742
                    break;
hgs
parents:
diff changeset
   743
                }
hgs
parents:
diff changeset
   744
            }
hgs
parents:
diff changeset
   745
            break;
hgs
parents:
diff changeset
   746
        case BTrace::ECodeSegs:
hgs
parents:
diff changeset
   747
            {
hgs
parents:
diff changeset
   748
            switch(aSubCategory)
hgs
parents:
diff changeset
   749
                {
hgs
parents:
diff changeset
   750
                case BTrace::ECodeSegCreated:
hgs
parents:
diff changeset
   751
                case BTrace::ECodeSegInfo:
hgs
parents:
diff changeset
   752
                    aIsPotentialPrimingTrace = ETrue;
hgs
parents:
diff changeset
   753
                    break;
hgs
parents:
diff changeset
   754
                default:
hgs
parents:
diff changeset
   755
                    aIsPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   756
                    break;
hgs
parents:
diff changeset
   757
                }
hgs
parents:
diff changeset
   758
            }
hgs
parents:
diff changeset
   759
            break;
hgs
parents:
diff changeset
   760
        case BTrace::EPaging:
hgs
parents:
diff changeset
   761
            {
hgs
parents:
diff changeset
   762
            switch(aSubCategory)
hgs
parents:
diff changeset
   763
                {
hgs
parents:
diff changeset
   764
                case BTrace::EPagingMemoryModel:
hgs
parents:
diff changeset
   765
                    aIsPotentialPrimingTrace = ETrue;
hgs
parents:
diff changeset
   766
                    break;
hgs
parents:
diff changeset
   767
                default:
hgs
parents:
diff changeset
   768
                    aIsPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   769
                    break;
hgs
parents:
diff changeset
   770
                }
hgs
parents:
diff changeset
   771
            }
hgs
parents:
diff changeset
   772
            break;
hgs
parents:
diff changeset
   773
        case BTrace::EThreadPriority:
hgs
parents:
diff changeset
   774
            {
hgs
parents:
diff changeset
   775
            switch(aSubCategory)
hgs
parents:
diff changeset
   776
                {
hgs
parents:
diff changeset
   777
                case BTrace::EProcessPriority:
hgs
parents:
diff changeset
   778
                case BTrace::EDThreadPriority:
hgs
parents:
diff changeset
   779
                case BTrace::ENThreadPriority:
hgs
parents:
diff changeset
   780
                    aIsPotentialPrimingTrace = ETrue;
hgs
parents:
diff changeset
   781
                    break;
hgs
parents:
diff changeset
   782
                default:
hgs
parents:
diff changeset
   783
                    aIsPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   784
                    break;
hgs
parents:
diff changeset
   785
                }
hgs
parents:
diff changeset
   786
            }
hgs
parents:
diff changeset
   787
            break;
hgs
parents:
diff changeset
   788
        case BTrace::EFastMutex:
hgs
parents:
diff changeset
   789
            {
hgs
parents:
diff changeset
   790
            switch(aSubCategory)
hgs
parents:
diff changeset
   791
                {
hgs
parents:
diff changeset
   792
                case BTrace::EFastMutexName:
hgs
parents:
diff changeset
   793
                    aIsPotentialPrimingTrace = ETrue;
hgs
parents:
diff changeset
   794
                    break;
hgs
parents:
diff changeset
   795
                default:
hgs
parents:
diff changeset
   796
                    aIsPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   797
                    break;
hgs
parents:
diff changeset
   798
                }
hgs
parents:
diff changeset
   799
            }
hgs
parents:
diff changeset
   800
            break;
hgs
parents:
diff changeset
   801
        case BTrace::ESymbianKernelSync:
hgs
parents:
diff changeset
   802
            {
hgs
parents:
diff changeset
   803
            switch(aSubCategory)
hgs
parents:
diff changeset
   804
                {
hgs
parents:
diff changeset
   805
                case BTrace::EMutexCreate:
hgs
parents:
diff changeset
   806
                case BTrace::ESemaphoreCreate:
hgs
parents:
diff changeset
   807
                case BTrace::ECondVarCreate:
hgs
parents:
diff changeset
   808
                    aIsPotentialPrimingTrace = ETrue;
hgs
parents:
diff changeset
   809
                    break;
hgs
parents:
diff changeset
   810
                default:
hgs
parents:
diff changeset
   811
                    aIsPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   812
                    break;
hgs
parents:
diff changeset
   813
                }
hgs
parents:
diff changeset
   814
            }
hgs
parents:
diff changeset
   815
            break;
hgs
parents:
diff changeset
   816
        case BTrace::EClientServer:
hgs
parents:
diff changeset
   817
            {
hgs
parents:
diff changeset
   818
            switch(aSubCategory)
hgs
parents:
diff changeset
   819
                {
hgs
parents:
diff changeset
   820
                case BTrace::EServerCreate:
hgs
parents:
diff changeset
   821
                case BTrace::ESessionAttach:
hgs
parents:
diff changeset
   822
                    aIsPotentialPrimingTrace = ETrue;
hgs
parents:
diff changeset
   823
                    break;
hgs
parents:
diff changeset
   824
                default:
hgs
parents:
diff changeset
   825
                    aIsPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   826
                    break;
hgs
parents:
diff changeset
   827
                }
hgs
parents:
diff changeset
   828
            }
hgs
parents:
diff changeset
   829
            break;
hgs
parents:
diff changeset
   830
        default:
hgs
parents:
diff changeset
   831
            err = KErrNotSupported;
hgs
parents:
diff changeset
   832
            break;
hgs
parents:
diff changeset
   833
        }
hgs
parents:
diff changeset
   834
    
hgs
parents:
diff changeset
   835
    return err;
hgs
parents:
diff changeset
   836
    }
hgs
parents:
diff changeset
   837
hgs
parents:
diff changeset
   838
/*
hgs
parents:
diff changeset
   839
 * If the next trace is a meta trace true is returned if it is the start of priming data for a given group ID
hgs
parents:
diff changeset
   840
 *
hgs
parents:
diff changeset
   841
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
   842
 * @param aGroupId Group ID of kernel priming data
hgs
parents:
diff changeset
   843
 * @param aCategory BTrace category of the current trace
hgs
parents:
diff changeset
   844
 * @param aSubCategory BTrace subcategory of the current trace
hgs
parents:
diff changeset
   845
 * @return True if start of priming data for given group ID, false otherwise
hgs
parents:
diff changeset
   846
 */
hgs
parents:
diff changeset
   847
TBool TTraceDataParser::IsStartOfKernelPrimingBatch(TUint8* aBuffer, TGroupId aGroupId, TUint8 aCategory, TUint8 aSubCategory)
hgs
parents:
diff changeset
   848
    {
hgs
parents:
diff changeset
   849
    TBool startOfBatch = EFalse;
hgs
parents:
diff changeset
   850
    if (aCategory == BTrace::EMetaTrace)
hgs
parents:
diff changeset
   851
        {
hgs
parents:
diff changeset
   852
        if (aSubCategory == BTrace::EMetaTraceFilterChange)
hgs
parents:
diff changeset
   853
            {
hgs
parents:
diff changeset
   854
            TUint8 metaCategory = aBuffer[0];
hgs
parents:
diff changeset
   855
            TUint8 isActive = aBuffer[1];
hgs
parents:
diff changeset
   856
            if (metaCategory == aGroupId && isActive)
hgs
parents:
diff changeset
   857
                {
hgs
parents:
diff changeset
   858
                startOfBatch = ETrue;
hgs
parents:
diff changeset
   859
                }
hgs
parents:
diff changeset
   860
            }        
hgs
parents:
diff changeset
   861
        }
hgs
parents:
diff changeset
   862
    return startOfBatch;
hgs
parents:
diff changeset
   863
    }
hgs
parents:
diff changeset
   864
hgs
parents:
diff changeset
   865
/*
hgs
parents:
diff changeset
   866
 * Use heuristics to work out if current trace is part of kernel priming data
hgs
parents:
diff changeset
   867
 *
hgs
parents:
diff changeset
   868
 * @param aCategory BTrace category of the trace data
hgs
parents:
diff changeset
   869
 * @param aSubCategory BTrace subcategory of the trace data
hgs
parents:
diff changeset
   870
 * @param aTimeDifference Time difference (in microseconds) since last trace for given category
hgs
parents:
diff changeset
   871
 * @param aIsInPrimingBatch Output parameter set to true if in priming data
hgs
parents:
diff changeset
   872
 * @param aFirstTrace Boolean used to indicate if this is first trace (so there is no valid time difference)
hgs
parents:
diff changeset
   873
 * @param aStartOfBatch Output parameter set to true if start of batch of kernel priming data
hgs
parents:
diff changeset
   874
 * @return Standard Symbian error code
hgs
parents:
diff changeset
   875
 */
hgs
parents:
diff changeset
   876
TInt TTraceDataParser::IsInPrimingBatch(TUint8  aCategory, 
hgs
parents:
diff changeset
   877
                                        TUint8  aSubCategory, 
hgs
parents:
diff changeset
   878
                                        TUint32 aTimeDifference, 
hgs
parents:
diff changeset
   879
                                        TBool&  aIsInPrimingBatch, 
hgs
parents:
diff changeset
   880
                                        TBool&  aFirstTrace, 
hgs
parents:
diff changeset
   881
                                        TBool&  aStartOfBatch)
hgs
parents:
diff changeset
   882
    {
hgs
parents:
diff changeset
   883
    TBool isPotentialPrimingTrace = EFalse;
hgs
parents:
diff changeset
   884
    TInt err = IsPotentialPrimingTrace(aCategory, aSubCategory, isPotentialPrimingTrace);
hgs
parents:
diff changeset
   885
    
hgs
parents:
diff changeset
   886
    // Look at timestamp to see if this is a new batch of traces
hgs
parents:
diff changeset
   887
    if (aFirstTrace)
hgs
parents:
diff changeset
   888
        {
hgs
parents:
diff changeset
   889
        aFirstTrace = EFalse;
hgs
parents:
diff changeset
   890
        }
hgs
parents:
diff changeset
   891
    else if (aTimeDifference > KMinMilliSecondsBatchGap * 1000)
hgs
parents:
diff changeset
   892
        {
hgs
parents:
diff changeset
   893
        aStartOfBatch = ETrue;
hgs
parents:
diff changeset
   894
        aIsInPrimingBatch = EFalse;
hgs
parents:
diff changeset
   895
        }
hgs
parents:
diff changeset
   896
    else
hgs
parents:
diff changeset
   897
        {
hgs
parents:
diff changeset
   898
        aStartOfBatch = EFalse;
hgs
parents:
diff changeset
   899
        }
hgs
parents:
diff changeset
   900
    
hgs
parents:
diff changeset
   901
    if (isPotentialPrimingTrace && aStartOfBatch)
hgs
parents:
diff changeset
   902
        {
hgs
parents:
diff changeset
   903
        aIsInPrimingBatch = ETrue;
hgs
parents:
diff changeset
   904
        aStartOfBatch = EFalse;
hgs
parents:
diff changeset
   905
        }
hgs
parents:
diff changeset
   906
    else if (!isPotentialPrimingTrace)
hgs
parents:
diff changeset
   907
        {
hgs
parents:
diff changeset
   908
        aIsInPrimingBatch = EFalse;
hgs
parents:
diff changeset
   909
        }
hgs
parents:
diff changeset
   910
    
hgs
parents:
diff changeset
   911
    return err;
hgs
parents:
diff changeset
   912
    }
hgs
parents:
diff changeset
   913
hgs
parents:
diff changeset
   914
/*
hgs
parents:
diff changeset
   915
 * Parse the trace data header
hgs
parents:
diff changeset
   916
 * 
hgs
parents:
diff changeset
   917
 * The following trace types are supported:
hgs
parents:
diff changeset
   918
 *     OST traces (ascii and binary)
hgs
parents:
diff changeset
   919
 *     XTIv3 traces (ascii and binary)
hgs
parents:
diff changeset
   920
 *     Traces from the Test Writer (ascii and binary)
hgs
parents:
diff changeset
   921
 *
hgs
parents:
diff changeset
   922
 * @param aData Buffer containing the trace data
hgs
parents:
diff changeset
   923
 * @param aSize Size of trace data buffer
hgs
parents:
diff changeset
   924
 * @param aTraceHeaderSettings Output parameters set to header settings of the trace data
hgs
parents:
diff changeset
   925
 * @return Standard Symbian error code
hgs
parents:
diff changeset
   926
 */
hgs
parents:
diff changeset
   927
TInt TTraceDataParser::ParseHeader(TUint8*&                 aData, 
hgs
parents:
diff changeset
   928
                                   TInt                     aSize, 
hgs
parents:
diff changeset
   929
                                   TTraceHeaderSettings&    aTraceHeaderSettings)
hgs
parents:
diff changeset
   930
    {
hgs
parents:
diff changeset
   931
    // Check buffer is large enough to contain header
hgs
parents:
diff changeset
   932
    aSize--;
hgs
parents:
diff changeset
   933
    if (aSize < 0)
hgs
parents:
diff changeset
   934
        {
hgs
parents:
diff changeset
   935
        return KErrOverflow;
hgs
parents:
diff changeset
   936
        }
hgs
parents:
diff changeset
   937
    
hgs
parents:
diff changeset
   938
    TInt err = KErrNone;    
hgs
parents:
diff changeset
   939
    TUint8* startOfData = aData;
hgs
parents:
diff changeset
   940
    aTraceHeaderSettings.iMultiPartType = 0;
hgs
parents:
diff changeset
   941
    aTraceHeaderSettings.iMultiPartTraceID = 0;
hgs
parents:
diff changeset
   942
    aTraceHeaderSettings.iPrintfTrace = EFalse;
hgs
parents:
diff changeset
   943
    aTraceHeaderSettings.iHeaderFlags = EFalse;
hgs
parents:
diff changeset
   944
    aTraceHeaderSettings.iFromTestWriter = EFalse;
hgs
parents:
diff changeset
   945
    TBool xtiTrace = EFalse;
hgs
parents:
diff changeset
   946
    TUint8 version = aData[0];                        // Version (1 byte)
hgs
parents:
diff changeset
   947
    aData++;
hgs
parents:
diff changeset
   948
    
hgs
parents:
diff changeset
   949
    if (version == KXtiHeaderVersion)
hgs
parents:
diff changeset
   950
        {
hgs
parents:
diff changeset
   951
        // Check buffer is large enough to contain header
hgs
parents:
diff changeset
   952
        aSize -= KMinSizeXtiHeader;
hgs
parents:
diff changeset
   953
        if (aSize < 0)
hgs
parents:
diff changeset
   954
            {
hgs
parents:
diff changeset
   955
            aData = startOfData;
hgs
parents:
diff changeset
   956
            return KErrOverflow;
hgs
parents:
diff changeset
   957
            }
hgs
parents:
diff changeset
   958
        xtiTrace = ETrue;
hgs
parents:
diff changeset
   959
        TUint8 xtiTraceType = aData[KXtiTraceTypeIndex-1];
hgs
parents:
diff changeset
   960
        if (xtiTraceType != KXtiProtocolIdSimpleTrace)
hgs
parents:
diff changeset
   961
            {
hgs
parents:
diff changeset
   962
            aTraceHeaderSettings.iPrintfTrace = ETrue;
hgs
parents:
diff changeset
   963
            aTraceHeaderSettings.iLengthOfPayload = aData[KXtiLengthIndex-1] - 15;
hgs
parents:
diff changeset
   964
            aData += KMinSizeXtiHeader;
hgs
parents:
diff changeset
   965
            }
hgs
parents:
diff changeset
   966
        else
hgs
parents:
diff changeset
   967
            {
hgs
parents:
diff changeset
   968
            // Check buffer is large enough to contain header
hgs
parents:
diff changeset
   969
            aSize -= 1;
hgs
parents:
diff changeset
   970
            if (aSize < 0)
hgs
parents:
diff changeset
   971
                {
hgs
parents:
diff changeset
   972
                aData = startOfData;
hgs
parents:
diff changeset
   973
                return KErrOverflow;
hgs
parents:
diff changeset
   974
                }
hgs
parents:
diff changeset
   975
            // Jump to start of OST buffer
hgs
parents:
diff changeset
   976
            aData += KMinSizeXtiHeader + 1;
hgs
parents:
diff changeset
   977
            version = aData[0];
hgs
parents:
diff changeset
   978
            aData++;
hgs
parents:
diff changeset
   979
            }
hgs
parents:
diff changeset
   980
        }
hgs
parents:
diff changeset
   981
    
hgs
parents:
diff changeset
   982
    if (version == KHeaderVersion) // Ost header version byte is correct
hgs
parents:
diff changeset
   983
        {
hgs
parents:
diff changeset
   984
        // Check buffer is large enough to contain header
hgs
parents:
diff changeset
   985
        aSize -= KMinSizeOstHeader;
hgs
parents:
diff changeset
   986
        if (aSize < 0)
hgs
parents:
diff changeset
   987
            {
hgs
parents:
diff changeset
   988
            aData = startOfData;
hgs
parents:
diff changeset
   989
            return KErrOverflow;
hgs
parents:
diff changeset
   990
            }
hgs
parents:
diff changeset
   991
        const TUint8 protocolId = aData[0];                 // Protocol ID (1 byte)
hgs
parents:
diff changeset
   992
        aData++;
hgs
parents:
diff changeset
   993
        if (xtiTrace)
hgs
parents:
diff changeset
   994
            {
hgs
parents:
diff changeset
   995
            aTraceHeaderSettings.iLengthOfPayload = aData[0];
hgs
parents:
diff changeset
   996
            aData++;
hgs
parents:
diff changeset
   997
            aSize++;
hgs
parents:
diff changeset
   998
            }
hgs
parents:
diff changeset
   999
        else
hgs
parents:
diff changeset
  1000
            {
hgs
parents:
diff changeset
  1001
            aTraceHeaderSettings.iLengthOfPayload = ReadUint16FromBuf(aData);        // Size (2 bytes)
hgs
parents:
diff changeset
  1002
            }
hgs
parents:
diff changeset
  1003
    
hgs
parents:
diff changeset
  1004
        if (protocolId == KProtocolIdSimpleTrace) // Normal binary data
hgs
parents:
diff changeset
  1005
            {
hgs
parents:
diff changeset
  1006
            // Check buffer is large enough to contain header
hgs
parents:
diff changeset
  1007
            aSize -= KMinSizeOstBinaryHeader;
hgs
parents:
diff changeset
  1008
            if (aSize < 0)
hgs
parents:
diff changeset
  1009
                {
hgs
parents:
diff changeset
  1010
                aData = startOfData;
hgs
parents:
diff changeset
  1011
                return KErrOverflow;
hgs
parents:
diff changeset
  1012
                }
hgs
parents:
diff changeset
  1013
            ReadUint32FromBuf(aData);                       // Timestamp 1 (4 bytes)
hgs
parents:
diff changeset
  1014
            aTraceHeaderSettings.iTimestamp = ReadUint32FromBuf(aData);          // Timestamp 2 (4 bytes)
hgs
parents:
diff changeset
  1015
            }
hgs
parents:
diff changeset
  1016
        else if (protocolId == KProtocolIdAscii) // Ascii Printf data
hgs
parents:
diff changeset
  1017
            {
hgs
parents:
diff changeset
  1018
            aTraceHeaderSettings.iPrintfTrace = ETrue;
hgs
parents:
diff changeset
  1019
            // Check buffer is large enough to contain header
hgs
parents:
diff changeset
  1020
            aSize -= KMinSizeOstAsciiHeader;
hgs
parents:
diff changeset
  1021
            if (aSize < 0)
hgs
parents:
diff changeset
  1022
                {
hgs
parents:
diff changeset
  1023
                aData = startOfData;
hgs
parents:
diff changeset
  1024
                return KErrOverflow;
hgs
parents:
diff changeset
  1025
                }
hgs
parents:
diff changeset
  1026
            aData += 8;
hgs
parents:
diff changeset
  1027
            aTraceHeaderSettings.iLengthOfPayload -= 8;
hgs
parents:
diff changeset
  1028
            }
hgs
parents:
diff changeset
  1029
        else // Protocol ID is incorrect
hgs
parents:
diff changeset
  1030
            {
hgs
parents:
diff changeset
  1031
            err = KErrCorrupt;
hgs
parents:
diff changeset
  1032
            }
hgs
parents:
diff changeset
  1033
        }
hgs
parents:
diff changeset
  1034
    else if (version == SYMBIAN_TRACE) // Trace data is binary data from Test Writer
hgs
parents:
diff changeset
  1035
        {
hgs
parents:
diff changeset
  1036
        aTraceHeaderSettings.iFromTestWriter = ETrue;
hgs
parents:
diff changeset
  1037
        }
hgs
parents:
diff changeset
  1038
    else if (version == PRINTF_TRACE) // Trace data is ascii data from Test Writer
hgs
parents:
diff changeset
  1039
        {
hgs
parents:
diff changeset
  1040
        aTraceHeaderSettings.iFromTestWriter = ETrue;
hgs
parents:
diff changeset
  1041
        aTraceHeaderSettings.iPrintfTrace = ETrue;
hgs
parents:
diff changeset
  1042
        // The end of the printf trace data will have null char, so use that to find end of payload
hgs
parents:
diff changeset
  1043
        TPtr8 printfString(aData, aSize, aSize);
hgs
parents:
diff changeset
  1044
        aTraceHeaderSettings.iLengthOfPayload = printfString.Locate(TChar(0));
hgs
parents:
diff changeset
  1045
        if (aTraceHeaderSettings.iLengthOfPayload >= 0)
hgs
parents:
diff changeset
  1046
            {
hgs
parents:
diff changeset
  1047
            aTraceHeaderSettings.iLengthOfPayload++;
hgs
parents:
diff changeset
  1048
            }
hgs
parents:
diff changeset
  1049
        else
hgs
parents:
diff changeset
  1050
            {
hgs
parents:
diff changeset
  1051
            err = KErrCorrupt;
hgs
parents:
diff changeset
  1052
            }
hgs
parents:
diff changeset
  1053
        }
hgs
parents:
diff changeset
  1054
    else if (version != KXtiHeaderVersion)
hgs
parents:
diff changeset
  1055
        {
hgs
parents:
diff changeset
  1056
        err = KErrCorrupt;
hgs
parents:
diff changeset
  1057
        
hgs
parents:
diff changeset
  1058
        if(aTraceHeaderSettings.iLengthOfPayload < 0 )
hgs
parents:
diff changeset
  1059
            {
hgs
parents:
diff changeset
  1060
            err = KErrOverflow;
hgs
parents:
diff changeset
  1061
            }
hgs
parents:
diff changeset
  1062
        }
hgs
parents:
diff changeset
  1063
              
hgs
parents:
diff changeset
  1064
    if (aTraceHeaderSettings.iPrintfTrace)
hgs
parents:
diff changeset
  1065
        {
hgs
parents:
diff changeset
  1066
        aTraceHeaderSettings.iTimestamp = 0;
hgs
parents:
diff changeset
  1067
        aTraceHeaderSettings.iComponentID = 0;
hgs
parents:
diff changeset
  1068
        aTraceHeaderSettings.iCategory = 0;
hgs
parents:
diff changeset
  1069
        aTraceHeaderSettings.iSubCategory = 0;
hgs
parents:
diff changeset
  1070
        aTraceHeaderSettings.iTraceWord = 0;
hgs
parents:
diff changeset
  1071
        }
hgs
parents:
diff changeset
  1072
    else if (err == KErrNone)
hgs
parents:
diff changeset
  1073
        {
hgs
parents:
diff changeset
  1074
        // Check buffer is large enough to contain header
hgs
parents:
diff changeset
  1075
        aSize -= KMinSizeBinaryHeader;
hgs
parents:
diff changeset
  1076
        if (aSize < 0)
hgs
parents:
diff changeset
  1077
            {
hgs
parents:
diff changeset
  1078
            aData = startOfData;
hgs
parents:
diff changeset
  1079
            return KErrOverflow;
hgs
parents:
diff changeset
  1080
            }
hgs
parents:
diff changeset
  1081
        aTraceHeaderSettings.iComponentID = ReadUint32FromBuf(aData, aTraceHeaderSettings.iFromTestWriter);    // ComponentId (4 bytes)
hgs
parents:
diff changeset
  1082
        aTraceHeaderSettings.iTraceWord = ReadUint32FromBuf(aData, aTraceHeaderSettings.iFromTestWriter);      // GroupId (2 bytes). TraceId (2 bytes)
hgs
parents:
diff changeset
  1083
        
hgs
parents:
diff changeset
  1084
        TUint8* startOfPayload = aData;
hgs
parents:
diff changeset
  1085
        TUint8 size;
hgs
parents:
diff changeset
  1086
        
hgs
parents:
diff changeset
  1087
        TBool testWriterHwData = EFalse;
hgs
parents:
diff changeset
  1088
#ifndef __WINS__
hgs
parents:
diff changeset
  1089
        testWriterHwData = aTraceHeaderSettings.iFromTestWriter;
hgs
parents:
diff changeset
  1090
#endif
hgs
parents:
diff changeset
  1091
hgs
parents:
diff changeset
  1092
        // now look at BTrace header and payload.
hgs
parents:
diff changeset
  1093
        if (!testWriterHwData)
hgs
parents:
diff changeset
  1094
            {
hgs
parents:
diff changeset
  1095
            size = aData[BTrace::ESizeIndex];
hgs
parents:
diff changeset
  1096
            aTraceHeaderSettings.iHeaderFlags = aData[BTrace::EFlagsIndex];
hgs
parents:
diff changeset
  1097
            aTraceHeaderSettings.iCategory = aData[BTrace::ECategoryIndex];
hgs
parents:
diff changeset
  1098
            aTraceHeaderSettings.iSubCategory = aData[BTrace::ESubCategoryIndex];
hgs
parents:
diff changeset
  1099
            }
hgs
parents:
diff changeset
  1100
        else
hgs
parents:
diff changeset
  1101
            {
hgs
parents:
diff changeset
  1102
            // endianess order is reversed for TestWriter on hw
hgs
parents:
diff changeset
  1103
            aTraceHeaderSettings.iSubCategory = aData[BTrace::ESizeIndex];
hgs
parents:
diff changeset
  1104
            aTraceHeaderSettings.iCategory = aData[BTrace::EFlagsIndex];
hgs
parents:
diff changeset
  1105
            aTraceHeaderSettings.iHeaderFlags = aData[BTrace::ECategoryIndex];
hgs
parents:
diff changeset
  1106
            size = aData[BTrace::ESubCategoryIndex];
hgs
parents:
diff changeset
  1107
            }
hgs
parents:
diff changeset
  1108
        
hgs
parents:
diff changeset
  1109
        aData+=4;
hgs
parents:
diff changeset
  1110
hgs
parents:
diff changeset
  1111
        //read header extensions
hgs
parents:
diff changeset
  1112
        if(aTraceHeaderSettings.iHeaderFlags & BTrace::EHeader2Present)
hgs
parents:
diff changeset
  1113
            {
hgs
parents:
diff changeset
  1114
            // Check buffer is large enough to contain header
hgs
parents:
diff changeset
  1115
            aSize -= 4;
hgs
parents:
diff changeset
  1116
            if (aSize < 0)
hgs
parents:
diff changeset
  1117
                {
hgs
parents:
diff changeset
  1118
                aData = startOfData;
hgs
parents:
diff changeset
  1119
                return KErrOverflow;
hgs
parents:
diff changeset
  1120
                }
hgs
parents:
diff changeset
  1121
            TUint32 header2 = Swap(ReadUint32FromBuf(aData, aTraceHeaderSettings.iFromTestWriter));
hgs
parents:
diff changeset
  1122
            aTraceHeaderSettings.iMultiPartType = header2 & BTrace::EMultipartFlagMask;
hgs
parents:
diff changeset
  1123
            }
hgs
parents:
diff changeset
  1124
        if(aTraceHeaderSettings.iHeaderFlags & BTrace::ETimestampPresent)
hgs
parents:
diff changeset
  1125
            {
hgs
parents:
diff changeset
  1126
            // Check buffer is large enough to contain header
hgs
parents:
diff changeset
  1127
            aSize -= 4;
hgs
parents:
diff changeset
  1128
            if (aSize < 0)
hgs
parents:
diff changeset
  1129
                {
hgs
parents:
diff changeset
  1130
                aData = startOfData;
hgs
parents:
diff changeset
  1131
                return KErrOverflow;
hgs
parents:
diff changeset
  1132
                }
hgs
parents:
diff changeset
  1133
            ReadUint32FromBuf(aData, aTraceHeaderSettings.iFromTestWriter);
hgs
parents:
diff changeset
  1134
            }
hgs
parents:
diff changeset
  1135
        if(aTraceHeaderSettings.iHeaderFlags & BTrace::ETimestamp2Present)
hgs
parents:
diff changeset
  1136
            {
hgs
parents:
diff changeset
  1137
            // Check buffer is large enough to contain header
hgs
parents:
diff changeset
  1138
            aSize -= 4;
hgs
parents:
diff changeset
  1139
            if (aSize < 0)
hgs
parents:
diff changeset
  1140
                {
hgs
parents:
diff changeset
  1141
                aData = startOfData;
hgs
parents:
diff changeset
  1142
                return KErrOverflow;
hgs
parents:
diff changeset
  1143
                }
hgs
parents:
diff changeset
  1144
            ReadUint32FromBuf(aData, aTraceHeaderSettings.iFromTestWriter);
hgs
parents:
diff changeset
  1145
            }
hgs
parents:
diff changeset
  1146
        if(aTraceHeaderSettings.iHeaderFlags & BTrace::EContextIdPresent)
hgs
parents:
diff changeset
  1147
            {
hgs
parents:
diff changeset
  1148
            // Check buffer is large enough to contain header
hgs
parents:
diff changeset
  1149
            aSize -= 4;
hgs
parents:
diff changeset
  1150
            if (aSize < 0)
hgs
parents:
diff changeset
  1151
                {
hgs
parents:
diff changeset
  1152
                aData = startOfData;
hgs
parents:
diff changeset
  1153
                return KErrOverflow;
hgs
parents:
diff changeset
  1154
                }
hgs
parents:
diff changeset
  1155
            ReadUint32FromBuf(aData, aTraceHeaderSettings.iFromTestWriter);
hgs
parents:
diff changeset
  1156
            }
hgs
parents:
diff changeset
  1157
        if(aTraceHeaderSettings.iHeaderFlags & BTrace::EPcPresent)
hgs
parents:
diff changeset
  1158
            {
hgs
parents:
diff changeset
  1159
            // Check buffer is large enough to contain header
hgs
parents:
diff changeset
  1160
            aSize -= 4;
hgs
parents:
diff changeset
  1161
            if (aSize < 0)
hgs
parents:
diff changeset
  1162
                {
hgs
parents:
diff changeset
  1163
                aData = startOfData;
hgs
parents:
diff changeset
  1164
                return KErrOverflow;
hgs
parents:
diff changeset
  1165
                }
hgs
parents:
diff changeset
  1166
            ReadUint32FromBuf(aData, aTraceHeaderSettings.iFromTestWriter);
hgs
parents:
diff changeset
  1167
            }
hgs
parents:
diff changeset
  1168
        if(aTraceHeaderSettings.iHeaderFlags & BTrace::EExtraPresent)
hgs
parents:
diff changeset
  1169
            {
hgs
parents:
diff changeset
  1170
            // Check buffer is large enough to contain header
hgs
parents:
diff changeset
  1171
            aSize -=4 ;
hgs
parents:
diff changeset
  1172
            if (aSize < 0)
hgs
parents:
diff changeset
  1173
                {
hgs
parents:
diff changeset
  1174
                aData = startOfData;
hgs
parents:
diff changeset
  1175
                return KErrOverflow;
hgs
parents:
diff changeset
  1176
                }
hgs
parents:
diff changeset
  1177
            aTraceHeaderSettings.iMultiPartTraceID = Swap(ReadUint32FromBuf(aData, aTraceHeaderSettings.iFromTestWriter));
hgs
parents:
diff changeset
  1178
            }
hgs
parents:
diff changeset
  1179
hgs
parents:
diff changeset
  1180
        if (!xtiTrace)
hgs
parents:
diff changeset
  1181
            {
hgs
parents:
diff changeset
  1182
            size = (size+3)&~3;  // make it 4 byte aligned
hgs
parents:
diff changeset
  1183
            }
hgs
parents:
diff changeset
  1184
        if (size == 0)
hgs
parents:
diff changeset
  1185
            {
hgs
parents:
diff changeset
  1186
            // This happens when the trace is larger than maximum size, and we can't use the BTrace size field
hgs
parents:
diff changeset
  1187
            // Instead calculate payload length based on size in OST header
hgs
parents:
diff changeset
  1188
            aTraceHeaderSettings.iLengthOfPayload -= (aData-startOfPayload)+16; // size of rest of payload
hgs
parents:
diff changeset
  1189
            }
hgs
parents:
diff changeset
  1190
        else
hgs
parents:
diff changeset
  1191
            {
hgs
parents:
diff changeset
  1192
            aTraceHeaderSettings.iLengthOfPayload = size-(aData-startOfPayload); // size of rest of payload
hgs
parents:
diff changeset
  1193
            }
hgs
parents:
diff changeset
  1194
        }
hgs
parents:
diff changeset
  1195
hgs
parents:
diff changeset
  1196
    
hgs
parents:
diff changeset
  1197
    // Check buffer is large enough to contain payload
hgs
parents:
diff changeset
  1198
    aSize -= aTraceHeaderSettings.iLengthOfPayload;
hgs
parents:
diff changeset
  1199
    if (aSize < 0)
hgs
parents:
diff changeset
  1200
        {
hgs
parents:
diff changeset
  1201
        aData = startOfData;
hgs
parents:
diff changeset
  1202
        err = KErrOverflow;
hgs
parents:
diff changeset
  1203
        }
hgs
parents:
diff changeset
  1204
    
hgs
parents:
diff changeset
  1205
    return err;
hgs
parents:
diff changeset
  1206
    }
hgs
parents:
diff changeset
  1207
hgs
parents:
diff changeset
  1208
/*
hgs
parents:
diff changeset
  1209
 * Get the data required to verify kernel priming traces for EThreadIdentification
hgs
parents:
diff changeset
  1210
 *
hgs
parents:
diff changeset
  1211
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
  1212
 * @param aSize Size of the trace buffer
hgs
parents:
diff changeset
  1213
 * @param aThreadAddr Output parameter set to address of current thread
hgs
parents:
diff changeset
  1214
 * @param aProcessAddr Output parameter set to address of current process
hgs
parents:
diff changeset
  1215
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  1216
 */
hgs
parents:
diff changeset
  1217
TInt TTraceDataParser::GetThreadPrimingVerificationDataL(TUint8*     aBuffer, 
hgs
parents:
diff changeset
  1218
                                                         TInt        aSize, 
hgs
parents:
diff changeset
  1219
                                                         TUint32&    aThreadAddr, 
hgs
parents:
diff changeset
  1220
                                                         TUint32&    aProcessAddr,
hgs
parents:
diff changeset
  1221
                                                         RFile*      aFile)
hgs
parents:
diff changeset
  1222
    {
hgs
parents:
diff changeset
  1223
    TInt    err = KErrNone;
hgs
parents:
diff changeset
  1224
    TInt    filePos = 0;
hgs
parents:
diff changeset
  1225
    TUint8* data = NULL;
hgs
parents:
diff changeset
  1226
    TUint8* startOfData = NULL;
hgs
parents:
diff changeset
  1227
    TUint8* endOfData = NULL;    
hgs
parents:
diff changeset
  1228
    RBuf8   fileBuffer;
hgs
parents:
diff changeset
  1229
    
hgs
parents:
diff changeset
  1230
    if (aFile)
hgs
parents:
diff changeset
  1231
        {
hgs
parents:
diff changeset
  1232
        // Create file buffer and read first chunk from file
hgs
parents:
diff changeset
  1233
        err = CreateFileBuffer(fileBuffer, *aFile);
hgs
parents:
diff changeset
  1234
        if (err != KErrNone)
hgs
parents:
diff changeset
  1235
            {
hgs
parents:
diff changeset
  1236
            return err;
hgs
parents:
diff changeset
  1237
            }
hgs
parents:
diff changeset
  1238
        fileBuffer.CleanupClosePushL();
hgs
parents:
diff changeset
  1239
        err = ReadNextChunkFromFile(fileBuffer, *aFile, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1240
        if (err != KErrNone)
hgs
parents:
diff changeset
  1241
            {
hgs
parents:
diff changeset
  1242
            CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  1243
            return err;
hgs
parents:
diff changeset
  1244
            }
hgs
parents:
diff changeset
  1245
        }
hgs
parents:
diff changeset
  1246
    else
hgs
parents:
diff changeset
  1247
        {
hgs
parents:
diff changeset
  1248
        data = aBuffer;
hgs
parents:
diff changeset
  1249
        startOfData = data;
hgs
parents:
diff changeset
  1250
        endOfData = data + aSize;
hgs
parents:
diff changeset
  1251
        }
hgs
parents:
diff changeset
  1252
    
hgs
parents:
diff changeset
  1253
    TInt            headerErr = KErrNone; 
hgs
parents:
diff changeset
  1254
    RThread         currentThread;            
hgs
parents:
diff changeset
  1255
    TUint32         tempThreadAddr;
hgs
parents:
diff changeset
  1256
    TUint32         tempProcessAddr;
hgs
parents:
diff changeset
  1257
    TThreadId       threadid = 0;
hgs
parents:
diff changeset
  1258
hgs
parents:
diff changeset
  1259
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
  1260
hgs
parents:
diff changeset
  1261
    err = KErrGeneral;
hgs
parents:
diff changeset
  1262
    
hgs
parents:
diff changeset
  1263
    while(data < endOfData)
hgs
parents:
diff changeset
  1264
        {
hgs
parents:
diff changeset
  1265
        headerErr = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
  1266
        
hgs
parents:
diff changeset
  1267
        if (aFile && headerErr == KErrOverflow)
hgs
parents:
diff changeset
  1268
            {
hgs
parents:
diff changeset
  1269
            // We don't have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  1270
            headerErr = ReadNextChunkFromFile(fileBuffer, *aFile, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1271
            if (headerErr == KErrNone)
hgs
parents:
diff changeset
  1272
                {
hgs
parents:
diff changeset
  1273
                continue;
hgs
parents:
diff changeset
  1274
                }
hgs
parents:
diff changeset
  1275
            }
hgs
parents:
diff changeset
  1276
        if (headerErr != KErrNone)
hgs
parents:
diff changeset
  1277
            {
hgs
parents:
diff changeset
  1278
            err = headerErr;
hgs
parents:
diff changeset
  1279
            break;
hgs
parents:
diff changeset
  1280
            }
hgs
parents:
diff changeset
  1281
        if ( (traceHeaderSettings.iCategory == BTrace::EThreadIdentification) && (traceHeaderSettings.iSubCategory == BTrace::EThreadId) )
hgs
parents:
diff changeset
  1282
            {
hgs
parents:
diff changeset
  1283
            tempThreadAddr = Swap(ReadUint32FromBuf(data, traceHeaderSettings.iFromTestWriter));
hgs
parents:
diff changeset
  1284
            tempProcessAddr = Swap(ReadUint32FromBuf(data, traceHeaderSettings.iFromTestWriter));
hgs
parents:
diff changeset
  1285
            threadid = Swap(ReadUint32FromBuf(data, traceHeaderSettings.iFromTestWriter));
hgs
parents:
diff changeset
  1286
            if (currentThread.Id() == threadid)
hgs
parents:
diff changeset
  1287
                {
hgs
parents:
diff changeset
  1288
                aThreadAddr = tempThreadAddr;
hgs
parents:
diff changeset
  1289
                aProcessAddr = tempProcessAddr;
hgs
parents:
diff changeset
  1290
                err = KErrNone;
hgs
parents:
diff changeset
  1291
                break;
hgs
parents:
diff changeset
  1292
                }
hgs
parents:
diff changeset
  1293
            }
hgs
parents:
diff changeset
  1294
        else
hgs
parents:
diff changeset
  1295
            {
hgs
parents:
diff changeset
  1296
            data += traceHeaderSettings.iLengthOfPayload; //go to next trace
hgs
parents:
diff changeset
  1297
            }
hgs
parents:
diff changeset
  1298
hgs
parents:
diff changeset
  1299
        if (aFile && data == endOfData)
hgs
parents:
diff changeset
  1300
            {
hgs
parents:
diff changeset
  1301
            // We might not have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  1302
            headerErr = ReadNextChunkFromFile(fileBuffer, *aFile, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1303
            if (headerErr != KErrNone)
hgs
parents:
diff changeset
  1304
                {
hgs
parents:
diff changeset
  1305
                err = headerErr;
hgs
parents:
diff changeset
  1306
                break;
hgs
parents:
diff changeset
  1307
                }
hgs
parents:
diff changeset
  1308
            }
hgs
parents:
diff changeset
  1309
        }
hgs
parents:
diff changeset
  1310
hgs
parents:
diff changeset
  1311
    if (aFile)
hgs
parents:
diff changeset
  1312
        {
hgs
parents:
diff changeset
  1313
        CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  1314
        }
hgs
parents:
diff changeset
  1315
hgs
parents:
diff changeset
  1316
    return err;
hgs
parents:
diff changeset
  1317
    }
hgs
parents:
diff changeset
  1318
hgs
parents:
diff changeset
  1319
hgs
parents:
diff changeset
  1320
/*
hgs
parents:
diff changeset
  1321
 * Get the data required to verify kernel priming traces for ECodeSegs
hgs
parents:
diff changeset
  1322
 *
hgs
parents:
diff changeset
  1323
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
  1324
 * @param aSize Size of the trace buffer
hgs
parents:
diff changeset
  1325
 * @param aSegAddr1 Output parameter set to address of first code seg
hgs
parents:
diff changeset
  1326
 * @param aSegAddr2 Output parameter set to address of second code seg
hgs
parents:
diff changeset
  1327
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  1328
 */
hgs
parents:
diff changeset
  1329
TInt TTraceDataParser::GetCodeSegsVerificationDataL(TUint8*  aBuffer, 
hgs
parents:
diff changeset
  1330
                                                    TInt     aSize, 
hgs
parents:
diff changeset
  1331
                                                    TUint32& aSegAddr1, 
hgs
parents:
diff changeset
  1332
                                                    TUint32& aSegAddr2,
hgs
parents:
diff changeset
  1333
                                                    RFile*   aFile)
hgs
parents:
diff changeset
  1334
    {
hgs
parents:
diff changeset
  1335
    TInt    err = KErrNone;
hgs
parents:
diff changeset
  1336
    TInt    filePos = 0;
hgs
parents:
diff changeset
  1337
    TUint8* data = NULL;
hgs
parents:
diff changeset
  1338
    TUint8* startOfData = NULL;
hgs
parents:
diff changeset
  1339
    TUint8* endOfData = NULL;    
hgs
parents:
diff changeset
  1340
    RBuf8   fileBuffer;
hgs
parents:
diff changeset
  1341
    
hgs
parents:
diff changeset
  1342
    if (aFile)
hgs
parents:
diff changeset
  1343
        {
hgs
parents:
diff changeset
  1344
        // Create file buffer and read first chunk from file
hgs
parents:
diff changeset
  1345
        err = CreateFileBuffer(fileBuffer, *aFile);
hgs
parents:
diff changeset
  1346
        if (err != KErrNone)
hgs
parents:
diff changeset
  1347
            {
hgs
parents:
diff changeset
  1348
            return err;
hgs
parents:
diff changeset
  1349
            }
hgs
parents:
diff changeset
  1350
        fileBuffer.CleanupClosePushL();
hgs
parents:
diff changeset
  1351
        err = ReadNextChunkFromFile(fileBuffer, *aFile, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1352
        if (err != KErrNone)
hgs
parents:
diff changeset
  1353
            {
hgs
parents:
diff changeset
  1354
            CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  1355
            return err;
hgs
parents:
diff changeset
  1356
            }
hgs
parents:
diff changeset
  1357
        }
hgs
parents:
diff changeset
  1358
    else
hgs
parents:
diff changeset
  1359
        {
hgs
parents:
diff changeset
  1360
        data = aBuffer;
hgs
parents:
diff changeset
  1361
        startOfData = data;
hgs
parents:
diff changeset
  1362
        endOfData = data + aSize;
hgs
parents:
diff changeset
  1363
        }
hgs
parents:
diff changeset
  1364
    
hgs
parents:
diff changeset
  1365
    TInt            headerErr = KErrNone; 
hgs
parents:
diff changeset
  1366
    TUint32         tempSegAddr;
hgs
parents:
diff changeset
  1367
hgs
parents:
diff changeset
  1368
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
  1369
hgs
parents:
diff changeset
  1370
    err = KErrGeneral;
hgs
parents:
diff changeset
  1371
    
hgs
parents:
diff changeset
  1372
    while(data < endOfData)
hgs
parents:
diff changeset
  1373
        {
hgs
parents:
diff changeset
  1374
        headerErr = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
  1375
        
hgs
parents:
diff changeset
  1376
        if (aFile && headerErr == KErrOverflow)
hgs
parents:
diff changeset
  1377
            {
hgs
parents:
diff changeset
  1378
            // We don't have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  1379
            headerErr = ReadNextChunkFromFile(fileBuffer, *aFile, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1380
            if (headerErr == KErrNone)
hgs
parents:
diff changeset
  1381
                {
hgs
parents:
diff changeset
  1382
                continue;
hgs
parents:
diff changeset
  1383
                }
hgs
parents:
diff changeset
  1384
            }
hgs
parents:
diff changeset
  1385
        if (headerErr != KErrNone)
hgs
parents:
diff changeset
  1386
            {
hgs
parents:
diff changeset
  1387
            err = headerErr;
hgs
parents:
diff changeset
  1388
            break;
hgs
parents:
diff changeset
  1389
            }
hgs
parents:
diff changeset
  1390
        if ( (traceHeaderSettings.iCategory == BTrace::ECodeSegs) && (traceHeaderSettings.iSubCategory == BTrace::ECodeSegCreated) )
hgs
parents:
diff changeset
  1391
            {
hgs
parents:
diff changeset
  1392
            tempSegAddr = Swap(ReadUint32FromBuf(data, traceHeaderSettings.iFromTestWriter));
hgs
parents:
diff changeset
  1393
            traceHeaderSettings.iLengthOfPayload -= 4;
hgs
parents:
diff changeset
  1394
            TPtr8 codeSegName(data,traceHeaderSettings.iLengthOfPayload,traceHeaderSettings.iLengthOfPayload); //should be name of the code seg
hgs
parents:
diff changeset
  1395
            codeSegName.Trim();
hgs
parents:
diff changeset
  1396
            if (StringsMatch(KCodeSegsName1(), codeSegName))
hgs
parents:
diff changeset
  1397
                {
hgs
parents:
diff changeset
  1398
                aSegAddr1 = tempSegAddr;
hgs
parents:
diff changeset
  1399
                }
hgs
parents:
diff changeset
  1400
            if (StringsMatch(KCodeSegsName2(), codeSegName))
hgs
parents:
diff changeset
  1401
                {
hgs
parents:
diff changeset
  1402
                aSegAddr2 = tempSegAddr;
hgs
parents:
diff changeset
  1403
                }
hgs
parents:
diff changeset
  1404
            if (aSegAddr1 != 0 && aSegAddr2 != 0)
hgs
parents:
diff changeset
  1405
                {
hgs
parents:
diff changeset
  1406
                err = KErrNone;
hgs
parents:
diff changeset
  1407
                break;
hgs
parents:
diff changeset
  1408
                }
hgs
parents:
diff changeset
  1409
            }
hgs
parents:
diff changeset
  1410
hgs
parents:
diff changeset
  1411
        data += traceHeaderSettings.iLengthOfPayload; //go to next trace
hgs
parents:
diff changeset
  1412
hgs
parents:
diff changeset
  1413
        if (aFile && data == endOfData)
hgs
parents:
diff changeset
  1414
            {
hgs
parents:
diff changeset
  1415
            // We might not have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  1416
            headerErr = ReadNextChunkFromFile(fileBuffer, *aFile, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1417
            if (headerErr != KErrNone)
hgs
parents:
diff changeset
  1418
                {
hgs
parents:
diff changeset
  1419
                err = headerErr;
hgs
parents:
diff changeset
  1420
                break;
hgs
parents:
diff changeset
  1421
                }
hgs
parents:
diff changeset
  1422
            }
hgs
parents:
diff changeset
  1423
        }
hgs
parents:
diff changeset
  1424
hgs
parents:
diff changeset
  1425
    if (aFile)
hgs
parents:
diff changeset
  1426
        {
hgs
parents:
diff changeset
  1427
        CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  1428
        }
hgs
parents:
diff changeset
  1429
    
hgs
parents:
diff changeset
  1430
    return err;
hgs
parents:
diff changeset
  1431
    }
hgs
parents:
diff changeset
  1432
hgs
parents:
diff changeset
  1433
/*
hgs
parents:
diff changeset
  1434
 * Get the data required to verify kernel priming traces
hgs
parents:
diff changeset
  1435
 *
hgs
parents:
diff changeset
  1436
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
  1437
 * @param aSize Size of the trace buffer
hgs
parents:
diff changeset
  1438
 * @param aGroupId Group ID of traces
hgs
parents:
diff changeset
  1439
 * @param aVerificationData1 Output parameter set to first data required
hgs
parents:
diff changeset
  1440
 * @param aVerificationData2 Output parameter set to second data required
hgs
parents:
diff changeset
  1441
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  1442
 */
hgs
parents:
diff changeset
  1443
TInt TTraceDataParser::GetPrimingVerificationDataL(TUint8*  aBuffer, 
hgs
parents:
diff changeset
  1444
                                                   TInt     aSize, 
hgs
parents:
diff changeset
  1445
                                                   TGroupId aGroupId, 
hgs
parents:
diff changeset
  1446
                                                   TUint32& aVerificationData1, 
hgs
parents:
diff changeset
  1447
                                                   TUint32& aVerificationData2,
hgs
parents:
diff changeset
  1448
                                                   RFile*   aFile)
hgs
parents:
diff changeset
  1449
    {
hgs
parents:
diff changeset
  1450
    TInt err = KErrNone;
hgs
parents:
diff changeset
  1451
    switch(aGroupId)
hgs
parents:
diff changeset
  1452
        {
hgs
parents:
diff changeset
  1453
        case BTrace::EThreadIdentification:
hgs
parents:
diff changeset
  1454
            err = GetThreadPrimingVerificationDataL(aBuffer, aSize, aVerificationData1, aVerificationData2, aFile);
hgs
parents:
diff changeset
  1455
            break;
hgs
parents:
diff changeset
  1456
        case BTrace::ECodeSegs:
hgs
parents:
diff changeset
  1457
            err = GetCodeSegsVerificationDataL(aBuffer, aSize, aVerificationData1, aVerificationData2, aFile);
hgs
parents:
diff changeset
  1458
            break;
hgs
parents:
diff changeset
  1459
        default:
hgs
parents:
diff changeset
  1460
            break;
hgs
parents:
diff changeset
  1461
        }
hgs
parents:
diff changeset
  1462
    return err;    
hgs
parents:
diff changeset
  1463
    }
hgs
parents:
diff changeset
  1464
hgs
parents:
diff changeset
  1465
/*
hgs
parents:
diff changeset
  1466
 * Parse trace data for kernel priming data
hgs
parents:
diff changeset
  1467
 * 
hgs
parents:
diff changeset
  1468
 * Note that this function can only verify priming data if the group ID is EThreadIdentification or EFastMutex,
hgs
parents:
diff changeset
  1469
 * otherwise KErrNotSupported is returned if aVerifyData is ETrue
hgs
parents:
diff changeset
  1470
 *
hgs
parents:
diff changeset
  1471
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
  1472
 * @param aGroupId Group ID of traces to parse
hgs
parents:
diff changeset
  1473
 * @param aNumPrimingTraces Output parameter set to number of priming traces found for given group ID
hgs
parents:
diff changeset
  1474
 * @param aNumTraces Output parameter set to total number of traces found for given group ID
hgs
parents:
diff changeset
  1475
 * @param aVerifyData Flag indicating if priming data should be verified
hgs
parents:
diff changeset
  1476
 * @param aVerificationData1 Optional first data required for verifying priming data
hgs
parents:
diff changeset
  1477
 * @param aVerificationData1 Optional second data required for verifying priming data
hgs
parents:
diff changeset
  1478
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  1479
 */
hgs
parents:
diff changeset
  1480
EXPORT_C TInt TTraceDataParser::ParsePrimingDataL(TDesC8&        aBuffer, 
hgs
parents:
diff changeset
  1481
                                                  TGroupId       aGroupId, 
hgs
parents:
diff changeset
  1482
                                                  TInt&          aNumPrimingTraces, 
hgs
parents:
diff changeset
  1483
                                                  TInt&          aNumTraces, 
hgs
parents:
diff changeset
  1484
                                                  TBool          aVerifyData, 
hgs
parents:
diff changeset
  1485
                                                  TUint32        aVerificationData1, 
hgs
parents:
diff changeset
  1486
                                                  TUint32        aVerificationData2)
hgs
parents:
diff changeset
  1487
    {
hgs
parents:
diff changeset
  1488
    aNumPrimingTraces = 0;
hgs
parents:
diff changeset
  1489
    aNumTraces = 0;
hgs
parents:
diff changeset
  1490
hgs
parents:
diff changeset
  1491
    TUint8*         data = (TUint8*) aBuffer.Ptr();
hgs
parents:
diff changeset
  1492
    TUint8*         endOfData = data + aBuffer.Size();    
hgs
parents:
diff changeset
  1493
    
hgs
parents:
diff changeset
  1494
    // If the output data is to be verified but no verification data provided, try getting it automatically
hgs
parents:
diff changeset
  1495
    if (aVerifyData && aVerificationData1 == 0 && aVerificationData2 == 0)
hgs
parents:
diff changeset
  1496
        {
hgs
parents:
diff changeset
  1497
        TInt err = GetPrimingVerificationDataL(data, endOfData-data, aGroupId, aVerificationData1, aVerificationData2);
hgs
parents:
diff changeset
  1498
        if (err != KErrNone)
hgs
parents:
diff changeset
  1499
            {
hgs
parents:
diff changeset
  1500
            return err;
hgs
parents:
diff changeset
  1501
            }
hgs
parents:
diff changeset
  1502
        }
hgs
parents:
diff changeset
  1503
    
hgs
parents:
diff changeset
  1504
    TInt            returnErr = KErrNone;
hgs
parents:
diff changeset
  1505
    TInt            dataVerificationErr = KErrNone;
hgs
parents:
diff changeset
  1506
    TInt            generalErr = KErrNone;
hgs
parents:
diff changeset
  1507
    TBool           firstTrace = ETrue;
hgs
parents:
diff changeset
  1508
    TBool           startOfBatch = ETrue;
hgs
parents:
diff changeset
  1509
    TBool           inPrimingData = EFalse;
hgs
parents:
diff changeset
  1510
    TBool           useMetaTraces = EFalse;
hgs
parents:
diff changeset
  1511
    TInt            numPotentialPrimingTraces = 0;
hgs
parents:
diff changeset
  1512
    TUint32         lastTimestamp = 0;
hgs
parents:
diff changeset
  1513
    TInt            elementsFound = 0;
hgs
parents:
diff changeset
  1514
    
hgs
parents:
diff changeset
  1515
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
  1516
hgs
parents:
diff changeset
  1517
    // Loop through all traces
hgs
parents:
diff changeset
  1518
    while (data < endOfData)
hgs
parents:
diff changeset
  1519
        {
hgs
parents:
diff changeset
  1520
        // Get trace info from header
hgs
parents:
diff changeset
  1521
        generalErr = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
  1522
        
hgs
parents:
diff changeset
  1523
        if (generalErr != KErrNone)
hgs
parents:
diff changeset
  1524
            {
hgs
parents:
diff changeset
  1525
            if (returnErr == KErrNone)
hgs
parents:
diff changeset
  1526
                {
hgs
parents:
diff changeset
  1527
                // Set error to return, if this is first error so far
hgs
parents:
diff changeset
  1528
                returnErr = generalErr;
hgs
parents:
diff changeset
  1529
                }
hgs
parents:
diff changeset
  1530
            break;
hgs
parents:
diff changeset
  1531
            }
hgs
parents:
diff changeset
  1532
hgs
parents:
diff changeset
  1533
        // If this is a meta trace, work out if it signifies start of kernel priming data for GID of interest
hgs
parents:
diff changeset
  1534
        if (traceHeaderSettings.iCategory == BTrace::EMetaTrace)
hgs
parents:
diff changeset
  1535
            {
hgs
parents:
diff changeset
  1536
            useMetaTraces = ETrue;
hgs
parents:
diff changeset
  1537
            startOfBatch = IsStartOfKernelPrimingBatch(data, aGroupId, traceHeaderSettings.iCategory, traceHeaderSettings.iSubCategory);
hgs
parents:
diff changeset
  1538
            }     
hgs
parents:
diff changeset
  1539
        
hgs
parents:
diff changeset
  1540
        // This is a trace of the correct GID/CID
hgs
parents:
diff changeset
  1541
        if ( (traceHeaderSettings.iComponentID == KKernelHooksOSTComponentUID) && (traceHeaderSettings.iCategory == aGroupId) )
hgs
parents:
diff changeset
  1542
            {
hgs
parents:
diff changeset
  1543
            // Increase the number of traces for this GID
hgs
parents:
diff changeset
  1544
            aNumTraces++;
hgs
parents:
diff changeset
  1545
hgs
parents:
diff changeset
  1546
            if (useMetaTraces)
hgs
parents:
diff changeset
  1547
                {
hgs
parents:
diff changeset
  1548
                // If data contains meta traces, work out if this is a priming trace
hgs
parents:
diff changeset
  1549
                if (startOfBatch)
hgs
parents:
diff changeset
  1550
                    {
hgs
parents:
diff changeset
  1551
                    // This is the start of a batch of priming traces
hgs
parents:
diff changeset
  1552
                    inPrimingData = ETrue;
hgs
parents:
diff changeset
  1553
                    startOfBatch = EFalse;
hgs
parents:
diff changeset
  1554
                    }
hgs
parents:
diff changeset
  1555
                if (inPrimingData)
hgs
parents:
diff changeset
  1556
                    {
hgs
parents:
diff changeset
  1557
                    // This is a priming trace, so increase number found for this GID
hgs
parents:
diff changeset
  1558
                    aNumPrimingTraces++; 
hgs
parents:
diff changeset
  1559
                    // If data is to be verified, attempt the verification
hgs
parents:
diff changeset
  1560
                    if (aVerifyData)
hgs
parents:
diff changeset
  1561
                        {
hgs
parents:
diff changeset
  1562
                        dataVerificationErr = VerifyPrimingData(data, traceHeaderSettings.iLengthOfPayload, traceHeaderSettings.iCategory, traceHeaderSettings.iSubCategory, elementsFound, traceHeaderSettings.iFromTestWriter, aVerificationData1, aVerificationData2);
hgs
parents:
diff changeset
  1563
                        }
hgs
parents:
diff changeset
  1564
                    }
hgs
parents:
diff changeset
  1565
                }
hgs
parents:
diff changeset
  1566
            else
hgs
parents:
diff changeset
  1567
                {
hgs
parents:
diff changeset
  1568
                // If data contains no meta traces, work out if this is a priming trace using heuristics
hgs
parents:
diff changeset
  1569
                generalErr = IsInPrimingBatch(traceHeaderSettings.iCategory, traceHeaderSettings.iSubCategory, traceHeaderSettings.iTimestamp-lastTimestamp, inPrimingData, firstTrace, startOfBatch);
hgs
parents:
diff changeset
  1570
                if ( (generalErr != KErrNone) && (returnErr == KErrNone) )
hgs
parents:
diff changeset
  1571
                    {
hgs
parents:
diff changeset
  1572
                    // Set error to return, if this is first error so far
hgs
parents:
diff changeset
  1573
                    returnErr = generalErr;
hgs
parents:
diff changeset
  1574
                    }
hgs
parents:
diff changeset
  1575
                lastTimestamp = traceHeaderSettings.iTimestamp;
hgs
parents:
diff changeset
  1576
                if (inPrimingData)
hgs
parents:
diff changeset
  1577
                    {
hgs
parents:
diff changeset
  1578
                    // This is possibly a priming trace, so increase potential number found for this GID
hgs
parents:
diff changeset
  1579
                    numPotentialPrimingTraces++;
hgs
parents:
diff changeset
  1580
                    // If data is to be verified, attempt the verification
hgs
parents:
diff changeset
  1581
                    if (aVerifyData)
hgs
parents:
diff changeset
  1582
                        {
hgs
parents:
diff changeset
  1583
                        dataVerificationErr = VerifyPrimingData(data, traceHeaderSettings.iLengthOfPayload, traceHeaderSettings.iCategory, traceHeaderSettings.iSubCategory, elementsFound, traceHeaderSettings.iFromTestWriter, aVerificationData1, aVerificationData2);
hgs
parents:
diff changeset
  1584
                        }
hgs
parents:
diff changeset
  1585
                    }
hgs
parents:
diff changeset
  1586
                else
hgs
parents:
diff changeset
  1587
                    {
hgs
parents:
diff changeset
  1588
                    // If we have enough potential priming traces, assume they are priming traces
hgs
parents:
diff changeset
  1589
                    if (numPotentialPrimingTraces >= KMinimumPrimingTracesInBatch)
hgs
parents:
diff changeset
  1590
                        {
hgs
parents:
diff changeset
  1591
                        aNumPrimingTraces += numPotentialPrimingTraces;
hgs
parents:
diff changeset
  1592
                        }
hgs
parents:
diff changeset
  1593
                    numPotentialPrimingTraces = 0;
hgs
parents:
diff changeset
  1594
                    }                
hgs
parents:
diff changeset
  1595
                }
hgs
parents:
diff changeset
  1596
            }
hgs
parents:
diff changeset
  1597
        else
hgs
parents:
diff changeset
  1598
            {
hgs
parents:
diff changeset
  1599
            // This is not a trace of the correct GID/CID
hgs
parents:
diff changeset
  1600
            inPrimingData = EFalse;
hgs
parents:
diff changeset
  1601
            }
hgs
parents:
diff changeset
  1602
        
hgs
parents:
diff changeset
  1603
        // Go to the next trace
hgs
parents:
diff changeset
  1604
        data+=traceHeaderSettings.iLengthOfPayload;
hgs
parents:
diff changeset
  1605
        }
hgs
parents:
diff changeset
  1606
hgs
parents:
diff changeset
  1607
    if (!useMetaTraces)
hgs
parents:
diff changeset
  1608
        {
hgs
parents:
diff changeset
  1609
        // If we have enough potential priming traces left over, assume they are priming traces
hgs
parents:
diff changeset
  1610
        if (numPotentialPrimingTraces >= KMinimumPrimingTracesInBatch)
hgs
parents:
diff changeset
  1611
            {
hgs
parents:
diff changeset
  1612
            aNumPrimingTraces += numPotentialPrimingTraces;
hgs
parents:
diff changeset
  1613
            }
hgs
parents:
diff changeset
  1614
        }
hgs
parents:
diff changeset
  1615
hgs
parents:
diff changeset
  1616
    if ( (dataVerificationErr != KErrNone) && (returnErr == KErrNone) )
hgs
parents:
diff changeset
  1617
        {
hgs
parents:
diff changeset
  1618
        // Set error to return, if this is first error so far
hgs
parents:
diff changeset
  1619
        returnErr = dataVerificationErr;
hgs
parents:
diff changeset
  1620
        }
hgs
parents:
diff changeset
  1621
    return returnErr;
hgs
parents:
diff changeset
  1622
    }
hgs
parents:
diff changeset
  1623
hgs
parents:
diff changeset
  1624
/*
hgs
parents:
diff changeset
  1625
 * Parse trace data for kernel priming data
hgs
parents:
diff changeset
  1626
 * 
hgs
parents:
diff changeset
  1627
 * Note that this function can only verify priming data if the group ID is EThreadIdentification or EFastMutex,
hgs
parents:
diff changeset
  1628
 * otherwise KErrNotSupported is returned if aVerifyData is ETrue
hgs
parents:
diff changeset
  1629
 *
hgs
parents:
diff changeset
  1630
 * @param aFilePath Full path of file containing the trace data
hgs
parents:
diff changeset
  1631
 * @param aFs File system object
hgs
parents:
diff changeset
  1632
 * @param aGroupId Group ID of traces to parse
hgs
parents:
diff changeset
  1633
 * @param aNumPrimingTraces Output parameter set to number of priming traces found for given group ID
hgs
parents:
diff changeset
  1634
 * @param aNumTraces Output parameter set to total number of traces found for given group ID
hgs
parents:
diff changeset
  1635
 * @param aVerifyData Flag indicating if priming data should be verified
hgs
parents:
diff changeset
  1636
 * @param aVerificationData1 Optional first data required for verifying priming data
hgs
parents:
diff changeset
  1637
 * @param aVerificationData1 Optional second data required for verifying priming data
hgs
parents:
diff changeset
  1638
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  1639
 */
hgs
parents:
diff changeset
  1640
EXPORT_C TInt TTraceDataParser::ParsePrimingDataL(const TDesC&   aFilePath,
hgs
parents:
diff changeset
  1641
                                                  RFs&           aFs, 
hgs
parents:
diff changeset
  1642
                                                  TGroupId       aGroupId, 
hgs
parents:
diff changeset
  1643
                                                  TInt&          aNumPrimingTraces, 
hgs
parents:
diff changeset
  1644
                                                  TInt&          aNumTraces, 
hgs
parents:
diff changeset
  1645
                                                  TBool          aVerifyData, 
hgs
parents:
diff changeset
  1646
                                                  TUint32        aVerificationData1, 
hgs
parents:
diff changeset
  1647
                                                  TUint32        aVerificationData2)
hgs
parents:
diff changeset
  1648
    {
hgs
parents:
diff changeset
  1649
    aNumPrimingTraces = 0;
hgs
parents:
diff changeset
  1650
    aNumTraces = 0;
hgs
parents:
diff changeset
  1651
    
hgs
parents:
diff changeset
  1652
    RFile file;
hgs
parents:
diff changeset
  1653
hgs
parents:
diff changeset
  1654
    // Open file with trace data
hgs
parents:
diff changeset
  1655
    TInt err = file.Open(aFs, aFilePath, EFileRead|EFileShareAny);
hgs
parents:
diff changeset
  1656
    if (err != KErrNone)
hgs
parents:
diff changeset
  1657
        {
hgs
parents:
diff changeset
  1658
        return err;
hgs
parents:
diff changeset
  1659
        }
hgs
parents:
diff changeset
  1660
    CleanupClosePushL(file);
hgs
parents:
diff changeset
  1661
    
hgs
parents:
diff changeset
  1662
    // If the output data is to be verified but no verification data provided, try getting it automatically
hgs
parents:
diff changeset
  1663
    if (aVerifyData && aVerificationData1 == 0 && aVerificationData2 == 0)
hgs
parents:
diff changeset
  1664
        {
hgs
parents:
diff changeset
  1665
        err = GetPrimingVerificationDataL(NULL, 0, aGroupId, aVerificationData1, aVerificationData2, &file);
hgs
parents:
diff changeset
  1666
        if (err != KErrNone)
hgs
parents:
diff changeset
  1667
            {
hgs
parents:
diff changeset
  1668
            CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  1669
            return err;
hgs
parents:
diff changeset
  1670
            }
hgs
parents:
diff changeset
  1671
        }
hgs
parents:
diff changeset
  1672
    
hgs
parents:
diff changeset
  1673
    RBuf8   fileBuffer;
hgs
parents:
diff changeset
  1674
    TInt    filePos = 0;
hgs
parents:
diff changeset
  1675
    
hgs
parents:
diff changeset
  1676
    // Create file buffer and read first chunk from file
hgs
parents:
diff changeset
  1677
    err = CreateFileBuffer(fileBuffer, file);
hgs
parents:
diff changeset
  1678
    if (err != KErrNone)
hgs
parents:
diff changeset
  1679
        {
hgs
parents:
diff changeset
  1680
        CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  1681
        return err;
hgs
parents:
diff changeset
  1682
        }
hgs
parents:
diff changeset
  1683
    fileBuffer.CleanupClosePushL();
hgs
parents:
diff changeset
  1684
    
hgs
parents:
diff changeset
  1685
    TUint8* data = NULL;
hgs
parents:
diff changeset
  1686
    TUint8* startOfData = NULL;
hgs
parents:
diff changeset
  1687
    TUint8* endOfData = NULL;    
hgs
parents:
diff changeset
  1688
hgs
parents:
diff changeset
  1689
    err = ReadNextChunkFromFile(fileBuffer, file, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1690
    if (err != KErrNone)
hgs
parents:
diff changeset
  1691
        {
hgs
parents:
diff changeset
  1692
        CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  1693
        CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  1694
        return err;
hgs
parents:
diff changeset
  1695
        }
hgs
parents:
diff changeset
  1696
hgs
parents:
diff changeset
  1697
    TInt            dataVerificationErr = KErrNone;
hgs
parents:
diff changeset
  1698
    TInt            generalErr = KErrNone;
hgs
parents:
diff changeset
  1699
    TBool           firstTrace = ETrue;
hgs
parents:
diff changeset
  1700
    TBool           startOfBatch = ETrue;
hgs
parents:
diff changeset
  1701
    TBool           inPrimingData = EFalse;
hgs
parents:
diff changeset
  1702
    TBool           useMetaTraces = EFalse;
hgs
parents:
diff changeset
  1703
    TInt            numPotentialPrimingTraces = 0;
hgs
parents:
diff changeset
  1704
    TUint32         lastTimestamp = 0;
hgs
parents:
diff changeset
  1705
    TInt            elementsFound = 0;
hgs
parents:
diff changeset
  1706
    
hgs
parents:
diff changeset
  1707
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
  1708
hgs
parents:
diff changeset
  1709
    // Loop through all traces
hgs
parents:
diff changeset
  1710
    while (data < endOfData)
hgs
parents:
diff changeset
  1711
        {
hgs
parents:
diff changeset
  1712
        // Get trace info from header
hgs
parents:
diff changeset
  1713
        generalErr = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
  1714
        
hgs
parents:
diff changeset
  1715
        if (generalErr == KErrOverflow)
hgs
parents:
diff changeset
  1716
            {
hgs
parents:
diff changeset
  1717
            // We don't have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  1718
            generalErr = ReadNextChunkFromFile(fileBuffer, file, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1719
            if (generalErr == KErrNone)
hgs
parents:
diff changeset
  1720
                {
hgs
parents:
diff changeset
  1721
                continue;
hgs
parents:
diff changeset
  1722
                }
hgs
parents:
diff changeset
  1723
            }
hgs
parents:
diff changeset
  1724
        if (generalErr != KErrNone)
hgs
parents:
diff changeset
  1725
            {
hgs
parents:
diff changeset
  1726
            if (err == KErrNone)
hgs
parents:
diff changeset
  1727
                {
hgs
parents:
diff changeset
  1728
                // Set error to return, if this is first error so far
hgs
parents:
diff changeset
  1729
                err = generalErr;
hgs
parents:
diff changeset
  1730
                }
hgs
parents:
diff changeset
  1731
            break;
hgs
parents:
diff changeset
  1732
            }
hgs
parents:
diff changeset
  1733
hgs
parents:
diff changeset
  1734
        // If this is a meta trace, work out if it signifies start of kernel priming data for GID of interest
hgs
parents:
diff changeset
  1735
        if (traceHeaderSettings.iCategory == BTrace::EMetaTrace)
hgs
parents:
diff changeset
  1736
            {
hgs
parents:
diff changeset
  1737
            useMetaTraces = ETrue;
hgs
parents:
diff changeset
  1738
            startOfBatch = IsStartOfKernelPrimingBatch(data, aGroupId, traceHeaderSettings.iCategory, traceHeaderSettings.iSubCategory);
hgs
parents:
diff changeset
  1739
            }     
hgs
parents:
diff changeset
  1740
        
hgs
parents:
diff changeset
  1741
        // This is a trace of the correct GID/CID
hgs
parents:
diff changeset
  1742
        if ( (traceHeaderSettings.iComponentID == KKernelHooksOSTComponentUID) && (traceHeaderSettings.iCategory == aGroupId) )
hgs
parents:
diff changeset
  1743
            {
hgs
parents:
diff changeset
  1744
            // Increase the number of traces for this GID
hgs
parents:
diff changeset
  1745
            aNumTraces++;
hgs
parents:
diff changeset
  1746
hgs
parents:
diff changeset
  1747
            if (useMetaTraces)
hgs
parents:
diff changeset
  1748
                {
hgs
parents:
diff changeset
  1749
                // If data contains meta traces, work out if this is a priming trace
hgs
parents:
diff changeset
  1750
                if (startOfBatch)
hgs
parents:
diff changeset
  1751
                    {
hgs
parents:
diff changeset
  1752
                    // This is the start of a batch of priming traces
hgs
parents:
diff changeset
  1753
                    inPrimingData = ETrue;
hgs
parents:
diff changeset
  1754
                    startOfBatch = EFalse;
hgs
parents:
diff changeset
  1755
                    }
hgs
parents:
diff changeset
  1756
                if (inPrimingData)
hgs
parents:
diff changeset
  1757
                    {
hgs
parents:
diff changeset
  1758
                    // This is a priming trace, so increase number found for this GID
hgs
parents:
diff changeset
  1759
                    aNumPrimingTraces++; 
hgs
parents:
diff changeset
  1760
                    // If data is to be verified, attempt the verification
hgs
parents:
diff changeset
  1761
                    if (aVerifyData)
hgs
parents:
diff changeset
  1762
                        {
hgs
parents:
diff changeset
  1763
                        dataVerificationErr = VerifyPrimingData(data, traceHeaderSettings.iLengthOfPayload, traceHeaderSettings.iCategory, traceHeaderSettings.iSubCategory, elementsFound, traceHeaderSettings.iFromTestWriter, aVerificationData1, aVerificationData2);
hgs
parents:
diff changeset
  1764
                        }
hgs
parents:
diff changeset
  1765
                    }
hgs
parents:
diff changeset
  1766
                }
hgs
parents:
diff changeset
  1767
            else
hgs
parents:
diff changeset
  1768
                {
hgs
parents:
diff changeset
  1769
                // If data contains no meta traces, work out if this is a priming trace using heuristics
hgs
parents:
diff changeset
  1770
                generalErr = IsInPrimingBatch(traceHeaderSettings.iCategory, traceHeaderSettings.iSubCategory, traceHeaderSettings.iTimestamp-lastTimestamp, inPrimingData, firstTrace, startOfBatch);
hgs
parents:
diff changeset
  1771
                if ( (generalErr != KErrNone) && (err == KErrNone) )
hgs
parents:
diff changeset
  1772
                    {
hgs
parents:
diff changeset
  1773
                    // Set error to return, if this is first error so far
hgs
parents:
diff changeset
  1774
                    err = generalErr;
hgs
parents:
diff changeset
  1775
                    }
hgs
parents:
diff changeset
  1776
                lastTimestamp = traceHeaderSettings.iTimestamp;
hgs
parents:
diff changeset
  1777
                if (inPrimingData)
hgs
parents:
diff changeset
  1778
                    {
hgs
parents:
diff changeset
  1779
                    // This is possibly a priming trace, so increase potential number found for this GID
hgs
parents:
diff changeset
  1780
                    numPotentialPrimingTraces++;
hgs
parents:
diff changeset
  1781
                    // If data is to be verified, attempt the verification
hgs
parents:
diff changeset
  1782
                    if (aVerifyData)
hgs
parents:
diff changeset
  1783
                        {
hgs
parents:
diff changeset
  1784
                        dataVerificationErr = VerifyPrimingData(data, traceHeaderSettings.iLengthOfPayload, traceHeaderSettings.iCategory, traceHeaderSettings.iSubCategory, elementsFound, traceHeaderSettings.iFromTestWriter, aVerificationData1, aVerificationData2);
hgs
parents:
diff changeset
  1785
                        }
hgs
parents:
diff changeset
  1786
                    }
hgs
parents:
diff changeset
  1787
                else
hgs
parents:
diff changeset
  1788
                    {
hgs
parents:
diff changeset
  1789
                    // If we have enough potential priming traces, assume they are priming traces
hgs
parents:
diff changeset
  1790
                    if (numPotentialPrimingTraces >= KMinimumPrimingTracesInBatch)
hgs
parents:
diff changeset
  1791
                        {
hgs
parents:
diff changeset
  1792
                        aNumPrimingTraces += numPotentialPrimingTraces;
hgs
parents:
diff changeset
  1793
                        }
hgs
parents:
diff changeset
  1794
                    numPotentialPrimingTraces = 0;
hgs
parents:
diff changeset
  1795
                    }                
hgs
parents:
diff changeset
  1796
                }
hgs
parents:
diff changeset
  1797
            }
hgs
parents:
diff changeset
  1798
        else
hgs
parents:
diff changeset
  1799
            {
hgs
parents:
diff changeset
  1800
            // This is not a trace of the correct GID/CID
hgs
parents:
diff changeset
  1801
            inPrimingData = EFalse;
hgs
parents:
diff changeset
  1802
            }
hgs
parents:
diff changeset
  1803
        
hgs
parents:
diff changeset
  1804
        // Go to the next trace
hgs
parents:
diff changeset
  1805
        data+=traceHeaderSettings.iLengthOfPayload;
hgs
parents:
diff changeset
  1806
hgs
parents:
diff changeset
  1807
        if (data == endOfData)
hgs
parents:
diff changeset
  1808
            {
hgs
parents:
diff changeset
  1809
            // We might not have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  1810
            generalErr = ReadNextChunkFromFile(fileBuffer, file, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1811
            if (generalErr != KErrNone)
hgs
parents:
diff changeset
  1812
                {
hgs
parents:
diff changeset
  1813
                if (err == KErrNone)
hgs
parents:
diff changeset
  1814
                    {
hgs
parents:
diff changeset
  1815
                    // Set error to return, if this is first error so far
hgs
parents:
diff changeset
  1816
                    err = generalErr;
hgs
parents:
diff changeset
  1817
                    }
hgs
parents:
diff changeset
  1818
                break;
hgs
parents:
diff changeset
  1819
                }
hgs
parents:
diff changeset
  1820
            }
hgs
parents:
diff changeset
  1821
        }
hgs
parents:
diff changeset
  1822
hgs
parents:
diff changeset
  1823
    if (!useMetaTraces)
hgs
parents:
diff changeset
  1824
        {
hgs
parents:
diff changeset
  1825
        // If we have enough potential priming traces left over, assume they are priming traces
hgs
parents:
diff changeset
  1826
        if (numPotentialPrimingTraces >= KMinimumPrimingTracesInBatch)
hgs
parents:
diff changeset
  1827
            {
hgs
parents:
diff changeset
  1828
            aNumPrimingTraces += numPotentialPrimingTraces;
hgs
parents:
diff changeset
  1829
            }
hgs
parents:
diff changeset
  1830
        }
hgs
parents:
diff changeset
  1831
hgs
parents:
diff changeset
  1832
    if ( (dataVerificationErr != KErrNone) && (err == KErrNone) )
hgs
parents:
diff changeset
  1833
        {
hgs
parents:
diff changeset
  1834
        // Set error to return, if this is first error so far
hgs
parents:
diff changeset
  1835
        err = dataVerificationErr;
hgs
parents:
diff changeset
  1836
        }
hgs
parents:
diff changeset
  1837
hgs
parents:
diff changeset
  1838
    CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  1839
    CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  1840
hgs
parents:
diff changeset
  1841
    return err;
hgs
parents:
diff changeset
  1842
    }
hgs
parents:
diff changeset
  1843
hgs
parents:
diff changeset
  1844
TInt TTraceDataParser::CreateFileBuffer(RBuf8&  aFileBuffer, 
hgs
parents:
diff changeset
  1845
                                        RFile&  aFile)
hgs
parents:
diff changeset
  1846
    {
hgs
parents:
diff changeset
  1847
    TInt fileSize;
hgs
parents:
diff changeset
  1848
    TInt err = aFile.Size(fileSize);
hgs
parents:
diff changeset
  1849
    if (err == KErrNone)
hgs
parents:
diff changeset
  1850
        {
hgs
parents:
diff changeset
  1851
        if (fileSize < KFileBufferSize)
hgs
parents:
diff changeset
  1852
            {
hgs
parents:
diff changeset
  1853
            err = aFileBuffer.Create(fileSize);
hgs
parents:
diff changeset
  1854
            }
hgs
parents:
diff changeset
  1855
        else
hgs
parents:
diff changeset
  1856
            {
hgs
parents:
diff changeset
  1857
            err = aFileBuffer.Create(KFileBufferSize);
hgs
parents:
diff changeset
  1858
            }
hgs
parents:
diff changeset
  1859
        }
hgs
parents:
diff changeset
  1860
    return err;
hgs
parents:
diff changeset
  1861
    }
hgs
parents:
diff changeset
  1862
hgs
parents:
diff changeset
  1863
TInt TTraceDataParser::ReadNextChunkFromFile(TDes8&   aFileBuffer, 
hgs
parents:
diff changeset
  1864
                                             RFile&   aFile, 
hgs
parents:
diff changeset
  1865
                                             TInt&    aFilePosition,
hgs
parents:
diff changeset
  1866
                                             TUint8*& aData,
hgs
parents:
diff changeset
  1867
                                             TUint8*& aStartOfData,
hgs
parents:
diff changeset
  1868
                                             TUint8*& aEndOfData)
hgs
parents:
diff changeset
  1869
    {
hgs
parents:
diff changeset
  1870
    aFilePosition += aData-aStartOfData;
hgs
parents:
diff changeset
  1871
    TInt err = aFile.Read(aFilePosition, aFileBuffer);
hgs
parents:
diff changeset
  1872
    if (err == KErrNone)
hgs
parents:
diff changeset
  1873
        {
hgs
parents:
diff changeset
  1874
        aData = (TUint8*) aFileBuffer.Ptr();
hgs
parents:
diff changeset
  1875
        aStartOfData = aData;
hgs
parents:
diff changeset
  1876
        aEndOfData = aData + aFileBuffer.Size();
hgs
parents:
diff changeset
  1877
        }
hgs
parents:
diff changeset
  1878
    return err;
hgs
parents:
diff changeset
  1879
    }
hgs
parents:
diff changeset
  1880
hgs
parents:
diff changeset
  1881
/*
hgs
parents:
diff changeset
  1882
 * Parse trace data for Printf data, returning the number of occurances of a given string
hgs
parents:
diff changeset
  1883
 *
hgs
parents:
diff changeset
  1884
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
  1885
 * @param aFindString String to search for
hgs
parents:
diff changeset
  1886
 * @param aNumFound Output parameter set to number of occurances of given string
hgs
parents:
diff changeset
  1887
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  1888
 */
hgs
parents:
diff changeset
  1889
EXPORT_C TInt TTraceDataParser::DataHasPrintfString(TDesC8&        aBuffer,
hgs
parents:
diff changeset
  1890
                                                    const TDesC8&  aFindString,
hgs
parents:
diff changeset
  1891
                                                    TInt&          aNumFound)
hgs
parents:
diff changeset
  1892
    {
hgs
parents:
diff changeset
  1893
    aNumFound = 0;
hgs
parents:
diff changeset
  1894
    
hgs
parents:
diff changeset
  1895
    TInt            err = KErrNone;
hgs
parents:
diff changeset
  1896
    TUint8*         data = (TUint8*) aBuffer.Ptr();
hgs
parents:
diff changeset
  1897
    TUint8*         endOfData = data + aBuffer.Size();    
hgs
parents:
diff changeset
  1898
    
hgs
parents:
diff changeset
  1899
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
  1900
hgs
parents:
diff changeset
  1901
    while(data < endOfData)
hgs
parents:
diff changeset
  1902
        {
hgs
parents:
diff changeset
  1903
        err = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
  1904
        
hgs
parents:
diff changeset
  1905
        if (err != KErrNone)
hgs
parents:
diff changeset
  1906
            {
hgs
parents:
diff changeset
  1907
            break;
hgs
parents:
diff changeset
  1908
            }
hgs
parents:
diff changeset
  1909
        if (traceHeaderSettings.iPrintfTrace)
hgs
parents:
diff changeset
  1910
            {
hgs
parents:
diff changeset
  1911
            TPtr8 printfString = ReadTracePrintf(data, traceHeaderSettings.iLengthOfPayload);
hgs
parents:
diff changeset
  1912
            if (StringsMatch(aFindString, printfString))
hgs
parents:
diff changeset
  1913
                {
hgs
parents:
diff changeset
  1914
                aNumFound++;
hgs
parents:
diff changeset
  1915
                }
hgs
parents:
diff changeset
  1916
            }
hgs
parents:
diff changeset
  1917
        data += traceHeaderSettings.iLengthOfPayload; //go to next trace
hgs
parents:
diff changeset
  1918
        }
hgs
parents:
diff changeset
  1919
hgs
parents:
diff changeset
  1920
    return err;
hgs
parents:
diff changeset
  1921
    }
hgs
parents:
diff changeset
  1922
hgs
parents:
diff changeset
  1923
/*
hgs
parents:
diff changeset
  1924
 * Parse trace data file for Printf data, returning the number of occurances of a given string
hgs
parents:
diff changeset
  1925
 *
hgs
parents:
diff changeset
  1926
 * @param aFilePath Full path of file containing the trace data
hgs
parents:
diff changeset
  1927
 * @param aFs File system object
hgs
parents:
diff changeset
  1928
 * @param aFindString String to search for
hgs
parents:
diff changeset
  1929
 * @param aNumFound Output parameter set to number of occurances of given string
hgs
parents:
diff changeset
  1930
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  1931
 */
hgs
parents:
diff changeset
  1932
EXPORT_C TInt TTraceDataParser::DataHasPrintfStringL(const TDesC&   aFilePath,
hgs
parents:
diff changeset
  1933
                                                     RFs&           aFs,
hgs
parents:
diff changeset
  1934
                                                     const TDesC8&  aFindString,
hgs
parents:
diff changeset
  1935
                                                     TInt&          aNumFound)
hgs
parents:
diff changeset
  1936
    {
hgs
parents:
diff changeset
  1937
    aNumFound = 0;
hgs
parents:
diff changeset
  1938
    
hgs
parents:
diff changeset
  1939
    RFile file;
hgs
parents:
diff changeset
  1940
hgs
parents:
diff changeset
  1941
    // Open file with trace data
hgs
parents:
diff changeset
  1942
    TInt err = file.Open(aFs, aFilePath, EFileRead|EFileShareAny);
hgs
parents:
diff changeset
  1943
    if (err != KErrNone)
hgs
parents:
diff changeset
  1944
        {
hgs
parents:
diff changeset
  1945
        return err;
hgs
parents:
diff changeset
  1946
        }
hgs
parents:
diff changeset
  1947
    CleanupClosePushL(file);
hgs
parents:
diff changeset
  1948
    
hgs
parents:
diff changeset
  1949
    RBuf8   fileBuffer;
hgs
parents:
diff changeset
  1950
    TInt    filePos = 0;
hgs
parents:
diff changeset
  1951
    
hgs
parents:
diff changeset
  1952
    // Create file buffer and read first chunk from file
hgs
parents:
diff changeset
  1953
    err = CreateFileBuffer(fileBuffer, file);
hgs
parents:
diff changeset
  1954
    if (err != KErrNone)
hgs
parents:
diff changeset
  1955
        {
hgs
parents:
diff changeset
  1956
        CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  1957
        return err;
hgs
parents:
diff changeset
  1958
        }
hgs
parents:
diff changeset
  1959
    fileBuffer.CleanupClosePushL();
hgs
parents:
diff changeset
  1960
    
hgs
parents:
diff changeset
  1961
    TUint8* data = NULL;
hgs
parents:
diff changeset
  1962
    TUint8* startOfData = NULL;
hgs
parents:
diff changeset
  1963
    TUint8* endOfData = NULL;    
hgs
parents:
diff changeset
  1964
hgs
parents:
diff changeset
  1965
    err = ReadNextChunkFromFile(fileBuffer, file, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1966
    if (err != KErrNone)
hgs
parents:
diff changeset
  1967
        {
hgs
parents:
diff changeset
  1968
        CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  1969
        CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  1970
        return err;
hgs
parents:
diff changeset
  1971
        }
hgs
parents:
diff changeset
  1972
hgs
parents:
diff changeset
  1973
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
  1974
hgs
parents:
diff changeset
  1975
    while(data < endOfData)
hgs
parents:
diff changeset
  1976
        {
hgs
parents:
diff changeset
  1977
        err = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
  1978
        
hgs
parents:
diff changeset
  1979
        if (err == KErrOverflow)
hgs
parents:
diff changeset
  1980
            {
hgs
parents:
diff changeset
  1981
            // We don't have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  1982
            err = ReadNextChunkFromFile(fileBuffer, file, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  1983
            if (err == KErrNone)
hgs
parents:
diff changeset
  1984
                {
hgs
parents:
diff changeset
  1985
                continue;
hgs
parents:
diff changeset
  1986
                }
hgs
parents:
diff changeset
  1987
            }
hgs
parents:
diff changeset
  1988
        if (err != KErrNone)
hgs
parents:
diff changeset
  1989
            {
hgs
parents:
diff changeset
  1990
            break;
hgs
parents:
diff changeset
  1991
            }
hgs
parents:
diff changeset
  1992
        if (traceHeaderSettings.iPrintfTrace)
hgs
parents:
diff changeset
  1993
            {
hgs
parents:
diff changeset
  1994
            TPtr8 printfString = ReadTracePrintf(data, traceHeaderSettings.iLengthOfPayload);
hgs
parents:
diff changeset
  1995
            if (StringsMatch(aFindString, printfString))
hgs
parents:
diff changeset
  1996
                {
hgs
parents:
diff changeset
  1997
                aNumFound++;
hgs
parents:
diff changeset
  1998
                }
hgs
parents:
diff changeset
  1999
            }
hgs
parents:
diff changeset
  2000
        data += traceHeaderSettings.iLengthOfPayload; //go to next trace
hgs
parents:
diff changeset
  2001
hgs
parents:
diff changeset
  2002
        if (data == endOfData)
hgs
parents:
diff changeset
  2003
            {
hgs
parents:
diff changeset
  2004
            // We might not have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  2005
            err = ReadNextChunkFromFile(fileBuffer, file, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  2006
            if (err != KErrNone)
hgs
parents:
diff changeset
  2007
                {
hgs
parents:
diff changeset
  2008
                break;
hgs
parents:
diff changeset
  2009
                }
hgs
parents:
diff changeset
  2010
            }
hgs
parents:
diff changeset
  2011
        }
hgs
parents:
diff changeset
  2012
hgs
parents:
diff changeset
  2013
    CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  2014
    CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  2015
hgs
parents:
diff changeset
  2016
    return err;
hgs
parents:
diff changeset
  2017
    }
hgs
parents:
diff changeset
  2018
hgs
parents:
diff changeset
  2019
/*
hgs
parents:
diff changeset
  2020
 * Parse trace data file for a sequence of traces
hgs
parents:
diff changeset
  2021
 *
hgs
parents:
diff changeset
  2022
 * @param aFilePath Full path of file containing the trace data
hgs
parents:
diff changeset
  2023
 * @param aFs File system object
hgs
parents:
diff changeset
  2024
 * @param aLastNumberFound Output parameter set to number in last occurances of given string
hgs
parents:
diff changeset
  2025
 * @param aNumDroppedTraces Output parameter set to number of dropped traces
hgs
parents:
diff changeset
  2026
 * @param aFindPrintfPattern Pattern that indicates where in the printf string the number will be, using an asterisk
hgs
parents:
diff changeset
  2027
 *                           This is only used if aGroupId = BTrace::ERDebugPrintf
hgs
parents:
diff changeset
  2028
 * @param aGroupId Group ID of traces to parse
hgs
parents:
diff changeset
  2029
 * @param aComponentID Component ID of traces to parse
hgs
parents:
diff changeset
  2030
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  2031
 */
hgs
parents:
diff changeset
  2032
EXPORT_C TInt TTraceDataParser::DataHasTraceSequenceL(const TDesC&   aFilePath,
hgs
parents:
diff changeset
  2033
                                                      RFs&           aFs,
hgs
parents:
diff changeset
  2034
                                                      TInt&          aLastNumberFound,
hgs
parents:
diff changeset
  2035
                                                      TInt&          aNumDroppedTraces, 
hgs
parents:
diff changeset
  2036
                                                      TDesC8*        aFindPrintfPattern,
hgs
parents:
diff changeset
  2037
                                                      TGroupId       aGroupId,
hgs
parents:
diff changeset
  2038
                                                      TComponentId   aComponentID)
hgs
parents:
diff changeset
  2039
    {
hgs
parents:
diff changeset
  2040
    aLastNumberFound = 0;
hgs
parents:
diff changeset
  2041
    aNumDroppedTraces = 0;
hgs
parents:
diff changeset
  2042
    
hgs
parents:
diff changeset
  2043
    RFile file;
hgs
parents:
diff changeset
  2044
hgs
parents:
diff changeset
  2045
    // Open file with trace data
hgs
parents:
diff changeset
  2046
    TInt err = file.Open(aFs, aFilePath, EFileRead|EFileShareAny);
hgs
parents:
diff changeset
  2047
    if (err != KErrNone)
hgs
parents:
diff changeset
  2048
        {
hgs
parents:
diff changeset
  2049
        return err;
hgs
parents:
diff changeset
  2050
        }
hgs
parents:
diff changeset
  2051
    CleanupClosePushL(file);
hgs
parents:
diff changeset
  2052
    
hgs
parents:
diff changeset
  2053
    RBuf8   fileBuffer;
hgs
parents:
diff changeset
  2054
    TInt    filePos = 0;
hgs
parents:
diff changeset
  2055
    
hgs
parents:
diff changeset
  2056
    // Create file buffer and read first chunk from file
hgs
parents:
diff changeset
  2057
    err = CreateFileBuffer(fileBuffer, file);
hgs
parents:
diff changeset
  2058
    if (err != KErrNone)
hgs
parents:
diff changeset
  2059
        {
hgs
parents:
diff changeset
  2060
        CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  2061
        return err;
hgs
parents:
diff changeset
  2062
        }
hgs
parents:
diff changeset
  2063
    fileBuffer.CleanupClosePushL();
hgs
parents:
diff changeset
  2064
    
hgs
parents:
diff changeset
  2065
    TUint8* data = NULL;
hgs
parents:
diff changeset
  2066
    TUint8* startOfData = NULL;
hgs
parents:
diff changeset
  2067
    TUint8* endOfData = NULL;    
hgs
parents:
diff changeset
  2068
hgs
parents:
diff changeset
  2069
    err = ReadNextChunkFromFile(fileBuffer, file, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  2070
    if (err != KErrNone)
hgs
parents:
diff changeset
  2071
        {
hgs
parents:
diff changeset
  2072
        CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  2073
        CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  2074
        return err;
hgs
parents:
diff changeset
  2075
        }
hgs
parents:
diff changeset
  2076
    
hgs
parents:
diff changeset
  2077
    TInt            currentNumber = 0;
hgs
parents:
diff changeset
  2078
    TInt            expectedNumber = 1;
hgs
parents:
diff changeset
  2079
    TBool           gotNumberFromTrace = EFalse;
hgs
parents:
diff changeset
  2080
    TBool           isDroppedTrace = EFalse;
hgs
parents:
diff changeset
  2081
hgs
parents:
diff changeset
  2082
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
  2083
hgs
parents:
diff changeset
  2084
    while(data < endOfData)
hgs
parents:
diff changeset
  2085
        {
hgs
parents:
diff changeset
  2086
        err = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
  2087
        
hgs
parents:
diff changeset
  2088
        if (err == KErrOverflow)
hgs
parents:
diff changeset
  2089
            {
hgs
parents:
diff changeset
  2090
            // We don't have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  2091
            err = ReadNextChunkFromFile(fileBuffer, file, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  2092
            if (err == KErrNone)
hgs
parents:
diff changeset
  2093
                {
hgs
parents:
diff changeset
  2094
                continue;
hgs
parents:
diff changeset
  2095
                }
hgs
parents:
diff changeset
  2096
            }
hgs
parents:
diff changeset
  2097
        if (err != KErrNone)
hgs
parents:
diff changeset
  2098
            {
hgs
parents:
diff changeset
  2099
            break;
hgs
parents:
diff changeset
  2100
            }
hgs
parents:
diff changeset
  2101
        
hgs
parents:
diff changeset
  2102
        gotNumberFromTrace = EFalse;
hgs
parents:
diff changeset
  2103
                    
hgs
parents:
diff changeset
  2104
        if (traceHeaderSettings.iPrintfTrace && aGroupId == BTrace::ERDebugPrintf)
hgs
parents:
diff changeset
  2105
            {
hgs
parents:
diff changeset
  2106
            TPtr8 printfString = ReadTracePrintf(data, traceHeaderSettings.iLengthOfPayload);
hgs
parents:
diff changeset
  2107
            // See if this is a printf that matches given string
hgs
parents:
diff changeset
  2108
            if (!aFindPrintfPattern)
hgs
parents:
diff changeset
  2109
                {
hgs
parents:
diff changeset
  2110
                err = KErrArgument;
hgs
parents:
diff changeset
  2111
                break;
hgs
parents:
diff changeset
  2112
                }
hgs
parents:
diff changeset
  2113
            else if (printfString.Match(*aFindPrintfPattern) != KErrNotFound)
hgs
parents:
diff changeset
  2114
                {
hgs
parents:
diff changeset
  2115
                // Get the line number from the string
hgs
parents:
diff changeset
  2116
                err = ParseStringForNumber(printfString, *aFindPrintfPattern, currentNumber);
hgs
parents:
diff changeset
  2117
                if (err != KErrNone)
hgs
parents:
diff changeset
  2118
                    {
hgs
parents:
diff changeset
  2119
                    // Could not extract number from printf, so stop and fail
hgs
parents:
diff changeset
  2120
                    break;
hgs
parents:
diff changeset
  2121
                    }
hgs
parents:
diff changeset
  2122
                gotNumberFromTrace = ETrue;
hgs
parents:
diff changeset
  2123
                } 
hgs
parents:
diff changeset
  2124
            // See if this is a dropped trace
hgs
parents:
diff changeset
  2125
            else if (printfString.Compare(KDroppedTrace()) == 0)
hgs
parents:
diff changeset
  2126
                {
hgs
parents:
diff changeset
  2127
                // If we get 2 dropped trace notifications in a row, return an error
hgs
parents:
diff changeset
  2128
                if (isDroppedTrace)    
hgs
parents:
diff changeset
  2129
                    {
hgs
parents:
diff changeset
  2130
                    err = KErrGeneral;
hgs
parents:
diff changeset
  2131
                    break;
hgs
parents:
diff changeset
  2132
                    }
hgs
parents:
diff changeset
  2133
                isDroppedTrace = ETrue;
hgs
parents:
diff changeset
  2134
                }
hgs
parents:
diff changeset
  2135
            else
hgs
parents:
diff changeset
  2136
                {
hgs
parents:
diff changeset
  2137
                isDroppedTrace = EFalse;
hgs
parents:
diff changeset
  2138
                }
hgs
parents:
diff changeset
  2139
            }
hgs
parents:
diff changeset
  2140
        else if (!traceHeaderSettings.iPrintfTrace && traceHeaderSettings.iCategory == aGroupId && traceHeaderSettings.iComponentID == aComponentID)
hgs
parents:
diff changeset
  2141
            {
hgs
parents:
diff changeset
  2142
            // check dropped trace flag
hgs
parents:
diff changeset
  2143
            if (traceHeaderSettings.iHeaderFlags & BTrace::EMissingRecord)
hgs
parents:
diff changeset
  2144
                {
hgs
parents:
diff changeset
  2145
                // If we get 2 dropped trace notifications in a row, return an error
hgs
parents:
diff changeset
  2146
                if (isDroppedTrace)
hgs
parents:
diff changeset
  2147
                    {
hgs
parents:
diff changeset
  2148
                    err = KErrGeneral;
hgs
parents:
diff changeset
  2149
                    break;
hgs
parents:
diff changeset
  2150
                    }
hgs
parents:
diff changeset
  2151
                isDroppedTrace = ETrue;
hgs
parents:
diff changeset
  2152
                }
hgs
parents:
diff changeset
  2153
            else
hgs
parents:
diff changeset
  2154
                {
hgs
parents:
diff changeset
  2155
                isDroppedTrace = EFalse;
hgs
parents:
diff changeset
  2156
                }
hgs
parents:
diff changeset
  2157
hgs
parents:
diff changeset
  2158
            if (traceHeaderSettings.iLengthOfPayload >= 4)
hgs
parents:
diff changeset
  2159
                {
hgs
parents:
diff changeset
  2160
                currentNumber = (TInt) Swap(ReadUint32FromBuf(data, traceHeaderSettings.iFromTestWriter));
hgs
parents:
diff changeset
  2161
                traceHeaderSettings.iLengthOfPayload -= 4;
hgs
parents:
diff changeset
  2162
                gotNumberFromTrace = ETrue;
hgs
parents:
diff changeset
  2163
                }                
hgs
parents:
diff changeset
  2164
            else
hgs
parents:
diff changeset
  2165
                {
hgs
parents:
diff changeset
  2166
                // Could not get number from trace, so stop and fail
hgs
parents:
diff changeset
  2167
                err = KErrGeneral;
hgs
parents:
diff changeset
  2168
                break;
hgs
parents:
diff changeset
  2169
                }
hgs
parents:
diff changeset
  2170
            }
hgs
parents:
diff changeset
  2171
hgs
parents:
diff changeset
  2172
        if (gotNumberFromTrace)
hgs
parents:
diff changeset
  2173
            {
hgs
parents:
diff changeset
  2174
            if (currentNumber < expectedNumber)
hgs
parents:
diff changeset
  2175
                {
hgs
parents:
diff changeset
  2176
                // Start of a new sequence, so stop
hgs
parents:
diff changeset
  2177
                break;
hgs
parents:
diff changeset
  2178
                }
hgs
parents:
diff changeset
  2179
            aLastNumberFound = currentNumber;
hgs
parents:
diff changeset
  2180
            if (aLastNumberFound != expectedNumber && !isDroppedTrace)
hgs
parents:
diff changeset
  2181
                {
hgs
parents:
diff changeset
  2182
                // A printf has been missed out with no notification, so stop and fail
hgs
parents:
diff changeset
  2183
                err = KErrGeneral;
hgs
parents:
diff changeset
  2184
                break;
hgs
parents:
diff changeset
  2185
                }
hgs
parents:
diff changeset
  2186
            else if (aLastNumberFound == expectedNumber && isDroppedTrace)
hgs
parents:
diff changeset
  2187
                {
hgs
parents:
diff changeset
  2188
                // A printf hasn't been missed out despite notification, so stop and fail
hgs
parents:
diff changeset
  2189
                err = KErrGeneral;
hgs
parents:
diff changeset
  2190
                break;
hgs
parents:
diff changeset
  2191
                }
hgs
parents:
diff changeset
  2192
            
hgs
parents:
diff changeset
  2193
            aNumDroppedTraces += (aLastNumberFound - expectedNumber);
hgs
parents:
diff changeset
  2194
            expectedNumber = aLastNumberFound + 1;
hgs
parents:
diff changeset
  2195
            
hgs
parents:
diff changeset
  2196
            if (traceHeaderSettings.iPrintfTrace)
hgs
parents:
diff changeset
  2197
                {
hgs
parents:
diff changeset
  2198
                isDroppedTrace = EFalse;
hgs
parents:
diff changeset
  2199
                }
hgs
parents:
diff changeset
  2200
            }
hgs
parents:
diff changeset
  2201
        
hgs
parents:
diff changeset
  2202
        data += traceHeaderSettings.iLengthOfPayload; //go to next trace
hgs
parents:
diff changeset
  2203
hgs
parents:
diff changeset
  2204
        if (data == endOfData)
hgs
parents:
diff changeset
  2205
            {
hgs
parents:
diff changeset
  2206
            // We might not have all the trace data, so read next chunk from file
hgs
parents:
diff changeset
  2207
            err = ReadNextChunkFromFile(fileBuffer, file, filePos, data, startOfData, endOfData);
hgs
parents:
diff changeset
  2208
            if (err != KErrNone)
hgs
parents:
diff changeset
  2209
                {
hgs
parents:
diff changeset
  2210
                break;
hgs
parents:
diff changeset
  2211
                }
hgs
parents:
diff changeset
  2212
            }
hgs
parents:
diff changeset
  2213
        }
hgs
parents:
diff changeset
  2214
hgs
parents:
diff changeset
  2215
    CleanupStack::PopAndDestroy(&fileBuffer); // close file buffer
hgs
parents:
diff changeset
  2216
    CleanupStack::PopAndDestroy(&file); // close file
hgs
parents:
diff changeset
  2217
hgs
parents:
diff changeset
  2218
    return err;
hgs
parents:
diff changeset
  2219
    }
hgs
parents:
diff changeset
  2220
hgs
parents:
diff changeset
  2221
/*
hgs
parents:
diff changeset
  2222
 * Get Printf string from single trace data
hgs
parents:
diff changeset
  2223
 *
hgs
parents:
diff changeset
  2224
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
  2225
 * @param aPrintfString Output parameter set to the print string in the trace data
hgs
parents:
diff changeset
  2226
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  2227
 */
hgs
parents:
diff changeset
  2228
EXPORT_C TInt TTraceDataParser::GetPrintfFromTrace(TDesC8& aBuffer, TDes8& aPrintfString)
hgs
parents:
diff changeset
  2229
    {
hgs
parents:
diff changeset
  2230
    TUint8*         data = (TUint8*) aBuffer.Ptr();
hgs
parents:
diff changeset
  2231
hgs
parents:
diff changeset
  2232
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
  2233
hgs
parents:
diff changeset
  2234
    TInt err = ParseHeader(data, aBuffer.Size(), traceHeaderSettings);
hgs
parents:
diff changeset
  2235
hgs
parents:
diff changeset
  2236
    if (err == KErrNone && traceHeaderSettings.iPrintfTrace)
hgs
parents:
diff changeset
  2237
        {
hgs
parents:
diff changeset
  2238
        aPrintfString.Copy(ReadTracePrintf(data, traceHeaderSettings.iLengthOfPayload));
hgs
parents:
diff changeset
  2239
        }
hgs
parents:
diff changeset
  2240
    
hgs
parents:
diff changeset
  2241
    return err;
hgs
parents:
diff changeset
  2242
    }
hgs
parents:
diff changeset
  2243
hgs
parents:
diff changeset
  2244
/*
hgs
parents:
diff changeset
  2245
 * Parse trace data for multipart data, returning the number of traces found and total size of trace data.
hgs
parents:
diff changeset
  2246
 * The data is expected to contain a sequence of integers, starting at 0
hgs
parents:
diff changeset
  2247
 *
hgs
parents:
diff changeset
  2248
 * @param aBuffer Buffer containing the trace data
hgs
parents:
diff changeset
  2249
 * @param aGroupId Group ID of traces to parse
hgs
parents:
diff changeset
  2250
 * @param aComponentID Component ID of traces to parse
hgs
parents:
diff changeset
  2251
 * @param aMultipartDataSize Output parameter set to total size of data in multipart trace
hgs
parents:
diff changeset
  2252
 * @param aNumMultipartTraces Output parameter set to number of traces that make up multipart trace
hgs
parents:
diff changeset
  2253
 * @return Standard Symbian error code
hgs
parents:
diff changeset
  2254
 */
hgs
parents:
diff changeset
  2255
EXPORT_C TInt TTraceDataParser::ValidateMultipartTraces(TDesC8&        aBuffer,
hgs
parents:
diff changeset
  2256
                                                        TGroupId       aGroupID, 
hgs
parents:
diff changeset
  2257
                                                        TComponentId   aComponentID, 
hgs
parents:
diff changeset
  2258
                                                        TInt&          aMultipartDataSize, 
hgs
parents:
diff changeset
  2259
                                                        TInt&          aNumMultipartTraces)
hgs
parents:
diff changeset
  2260
    {
hgs
parents:
diff changeset
  2261
    aMultipartDataSize = 0;
hgs
parents:
diff changeset
  2262
    aNumMultipartTraces = 0;
hgs
parents:
diff changeset
  2263
    
hgs
parents:
diff changeset
  2264
    TInt            err = KErrNone;
hgs
parents:
diff changeset
  2265
    TUint8*         data = (TUint8*) aBuffer.Ptr();
hgs
parents:
diff changeset
  2266
    TUint8*         endOfData = data + aBuffer.Size();    
hgs
parents:
diff changeset
  2267
    TUint8          currentNumber = 0;
hgs
parents:
diff changeset
  2268
    TUint8          expectedNumber = 0;
hgs
parents:
diff changeset
  2269
    TUint32         expectedMultiPartTraceID = 0;
hgs
parents:
diff changeset
  2270
    TBool           foundStartOfMultipart = EFalse;
hgs
parents:
diff changeset
  2271
    TBool           foundEndOfMultipart = EFalse;
hgs
parents:
diff changeset
  2272
    TBool           isMultipartTrace = EFalse;
hgs
parents:
diff changeset
  2273
    
hgs
parents:
diff changeset
  2274
    TTraceHeaderSettings  traceHeaderSettings;
hgs
parents:
diff changeset
  2275
hgs
parents:
diff changeset
  2276
    while(data < endOfData)
hgs
parents:
diff changeset
  2277
        {
hgs
parents:
diff changeset
  2278
        err = ParseHeader(data, endOfData-data, traceHeaderSettings);
hgs
parents:
diff changeset
  2279
        if (err != KErrNone)
hgs
parents:
diff changeset
  2280
            {
hgs
parents:
diff changeset
  2281
            return err;
hgs
parents:
diff changeset
  2282
            }
hgs
parents:
diff changeset
  2283
               
hgs
parents:
diff changeset
  2284
        // Only look at traces with correct group ID / component ID
hgs
parents:
diff changeset
  2285
        if (traceHeaderSettings.iCategory == aGroupID && traceHeaderSettings.iComponentID == aComponentID)
hgs
parents:
diff changeset
  2286
            {
hgs
parents:
diff changeset
  2287
            isMultipartTrace = EFalse;
hgs
parents:
diff changeset
  2288
            if (traceHeaderSettings.iMultiPartType == BTrace::EMultipartFirst ||
hgs
parents:
diff changeset
  2289
                traceHeaderSettings.iMultiPartType == BTrace::EMultipartMiddle ||
hgs
parents:
diff changeset
  2290
                traceHeaderSettings.iMultiPartType == BTrace::EMultipartLast)
hgs
parents:
diff changeset
  2291
                {
hgs
parents:
diff changeset
  2292
                isMultipartTrace = ETrue;
hgs
parents:
diff changeset
  2293
                }
hgs
parents:
diff changeset
  2294
            
hgs
parents:
diff changeset
  2295
            if (!isMultipartTrace)
hgs
parents:
diff changeset
  2296
                {
hgs
parents:
diff changeset
  2297
                // If not a multipart trace, then this one trace should contain all data
hgs
parents:
diff changeset
  2298
                aNumMultipartTraces = 1;
hgs
parents:
diff changeset
  2299
                aMultipartDataSize = traceHeaderSettings.iLengthOfPayload;
hgs
parents:
diff changeset
  2300
                // If already found some of the data then we shouldn't have this trace
hgs
parents:
diff changeset
  2301
                if (foundStartOfMultipart || foundEndOfMultipart)
hgs
parents:
diff changeset
  2302
                    {
hgs
parents:
diff changeset
  2303
                    return KErrCorrupt;
hgs
parents:
diff changeset
  2304
                    }
hgs
parents:
diff changeset
  2305
                foundStartOfMultipart = ETrue;
hgs
parents:
diff changeset
  2306
                foundEndOfMultipart = ETrue;
hgs
parents:
diff changeset
  2307
hgs
parents:
diff changeset
  2308
                // Validate payload
hgs
parents:
diff changeset
  2309
                while (traceHeaderSettings.iLengthOfPayload > 0)
hgs
parents:
diff changeset
  2310
                    {
hgs
parents:
diff changeset
  2311
                    currentNumber = (TInt) data[0];
hgs
parents:
diff changeset
  2312
                    data++;
hgs
parents:
diff changeset
  2313
                    // Adjust length of payload remaining
hgs
parents:
diff changeset
  2314
                    traceHeaderSettings.iLengthOfPayload -= 1;   
hgs
parents:
diff changeset
  2315
                    if (currentNumber != expectedNumber)
hgs
parents:
diff changeset
  2316
                        {
hgs
parents:
diff changeset
  2317
                        if (traceHeaderSettings.iLengthOfPayload >= 4 || currentNumber != 0)
hgs
parents:
diff changeset
  2318
                            {
hgs
parents:
diff changeset
  2319
                            // Data is 4-byte aligned, so it's ok to have up to 3 zeros at the end of payload
hgs
parents:
diff changeset
  2320
                            return KErrCorrupt;
hgs
parents:
diff changeset
  2321
                            }
hgs
parents:
diff changeset
  2322
                        // This byte is zero padding, so not part of data
hgs
parents:
diff changeset
  2323
                        aMultipartDataSize--;
hgs
parents:
diff changeset
  2324
                        }
hgs
parents:
diff changeset
  2325
                    expectedNumber++;
hgs
parents:
diff changeset
  2326
                    }
hgs
parents:
diff changeset
  2327
                }
hgs
parents:
diff changeset
  2328
            // Only look at multipart traces with correct multipart trace ID
hgs
parents:
diff changeset
  2329
            else if (traceHeaderSettings.iMultiPartTraceID == expectedMultiPartTraceID || expectedMultiPartTraceID == 0)
hgs
parents:
diff changeset
  2330
                {
hgs
parents:
diff changeset
  2331
                aNumMultipartTraces++;
hgs
parents:
diff changeset
  2332
                
hgs
parents:
diff changeset
  2333
                // If already found all data then we shouldn't get another trace with this ID
hgs
parents:
diff changeset
  2334
                if (foundEndOfMultipart)
hgs
parents:
diff changeset
  2335
                    {
hgs
parents:
diff changeset
  2336
                    return KErrCorrupt;
hgs
parents:
diff changeset
  2337
                    }
hgs
parents:
diff changeset
  2338
                
hgs
parents:
diff changeset
  2339
                // Trace is start of multipart
hgs
parents:
diff changeset
  2340
                if (traceHeaderSettings.iMultiPartType == BTrace::EMultipartFirst)
hgs
parents:
diff changeset
  2341
                    {
hgs
parents:
diff changeset
  2342
                    // If already found start of data then we shouldn't get this part
hgs
parents:
diff changeset
  2343
                    if (foundStartOfMultipart)
hgs
parents:
diff changeset
  2344
                        {
hgs
parents:
diff changeset
  2345
                        return KErrCorrupt;
hgs
parents:
diff changeset
  2346
                        }
hgs
parents:
diff changeset
  2347
                    foundStartOfMultipart = ETrue;
hgs
parents:
diff changeset
  2348
                    aMultipartDataSize = 0;
hgs
parents:
diff changeset
  2349
                    
hgs
parents:
diff changeset
  2350
                    // Set the expected multipart trace ID
hgs
parents:
diff changeset
  2351
                    expectedMultiPartTraceID = traceHeaderSettings.iMultiPartTraceID;                    
hgs
parents:
diff changeset
  2352
                    }
hgs
parents:
diff changeset
  2353
                else if (traceHeaderSettings.iMultiPartType == BTrace::EMultipartMiddle ||
hgs
parents:
diff changeset
  2354
                         traceHeaderSettings.iMultiPartType == BTrace::EMultipartLast)
hgs
parents:
diff changeset
  2355
                    {
hgs
parents:
diff changeset
  2356
                    // If not yet found start of data then we shouldn't get this part
hgs
parents:
diff changeset
  2357
                    if (!foundStartOfMultipart)
hgs
parents:
diff changeset
  2358
                        {
hgs
parents:
diff changeset
  2359
                        return KErrCorrupt;
hgs
parents:
diff changeset
  2360
                        }
hgs
parents:
diff changeset
  2361
                    }
hgs
parents:
diff changeset
  2362
                
hgs
parents:
diff changeset
  2363
                // Add length of payload to size of total data found
hgs
parents:
diff changeset
  2364
                aMultipartDataSize += traceHeaderSettings.iLengthOfPayload;
hgs
parents:
diff changeset
  2365
hgs
parents:
diff changeset
  2366
                while (traceHeaderSettings.iLengthOfPayload > 0)
hgs
parents:
diff changeset
  2367
                    {
hgs
parents:
diff changeset
  2368
                    // Validate the next part of payload
hgs
parents:
diff changeset
  2369
                    currentNumber = (TInt) data[0];
hgs
parents:
diff changeset
  2370
                    data++;
hgs
parents:
diff changeset
  2371
                    // Adjust length of payload remaining
hgs
parents:
diff changeset
  2372
                    traceHeaderSettings.iLengthOfPayload -= 1;   
hgs
parents:
diff changeset
  2373
                    if (currentNumber != expectedNumber)
hgs
parents:
diff changeset
  2374
                        {
hgs
parents:
diff changeset
  2375
                        if (traceHeaderSettings.iLengthOfPayload >= 4 || currentNumber != 0)
hgs
parents:
diff changeset
  2376
                            {
hgs
parents:
diff changeset
  2377
                            // Data is 4-byte aligned, so it's ok to have up to 3 zeros at the end of payload
hgs
parents:
diff changeset
  2378
                            return KErrCorrupt;
hgs
parents:
diff changeset
  2379
                            }
hgs
parents:
diff changeset
  2380
                        // This byte is zero padding, so not part of data
hgs
parents:
diff changeset
  2381
                        aMultipartDataSize--;
hgs
parents:
diff changeset
  2382
                        }
hgs
parents:
diff changeset
  2383
                    expectedNumber++;
hgs
parents:
diff changeset
  2384
                    }
hgs
parents:
diff changeset
  2385
hgs
parents:
diff changeset
  2386
                if (traceHeaderSettings.iMultiPartType == BTrace::EMultipartLast)
hgs
parents:
diff changeset
  2387
                    {                    
hgs
parents:
diff changeset
  2388
                    // Found end of trace data
hgs
parents:
diff changeset
  2389
                    foundEndOfMultipart = ETrue;
hgs
parents:
diff changeset
  2390
                    }
hgs
parents:
diff changeset
  2391
                }
hgs
parents:
diff changeset
  2392
            }
hgs
parents:
diff changeset
  2393
        
hgs
parents:
diff changeset
  2394
        data += traceHeaderSettings.iLengthOfPayload; //go to next trace
hgs
parents:
diff changeset
  2395
        }
hgs
parents:
diff changeset
  2396
hgs
parents:
diff changeset
  2397
    if (!foundEndOfMultipart)
hgs
parents:
diff changeset
  2398
        {
hgs
parents:
diff changeset
  2399
        // Did not find end of trace data, so return KErrNotFound
hgs
parents:
diff changeset
  2400
        err = KErrNotFound;
hgs
parents:
diff changeset
  2401
        }
hgs
parents:
diff changeset
  2402
    return err;
hgs
parents:
diff changeset
  2403
    }