diff -r 000000000000 -r dfb7c4ff071f commsfwtools/commstools/utracedecoder/src/utraceframe.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commsfwtools/commstools/utracedecoder/src/utraceframe.cpp Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,591 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include +#include + +#include "utraceframe.h" +#include "e32btrace.h" +#include "util.h" + +CUTraceFrame::CUTraceFrame(const unsigned char* aFrameData, unsigned int aEntryNumber) + { + SetFrameBuffer(aFrameData); + iEventEntryNumber = aEntryNumber; + } + +CUTraceFrame::~CUTraceFrame() + { + delete [] iFrameBuffer; + } + + +void CUTraceFrame::SetFrameBuffer(const unsigned char *aData) + { + int length = aData[0]; + iFrameBuffer = new unsigned char[length + 4]; + memset(iFrameBuffer, 0, length + 4); //need to do this so payload() doesnt blow out when used as string + memcpy((char *)iFrameBuffer, (const char*)aData, length); + } + + +unsigned char* CUTraceFrame::Data() const + { + // Get a pointer to the data after the header + unsigned char *p = (unsigned char*)(iFrameBuffer + CalculateEntryOffset(0)); + + // Make adjustments for any extra fields such as multipart information + // and the arg1 value + if (IsMultiPart()) + { + /* + The structure of the data part of each trace record in a multipart trace is described + below. In this description, the following labels are used. + - A is the initial 4 bytes of data; the a1 argument of BTraceBig. + - D is the array of bytes of additional data; the aData argument of BTraceBig. + - N is the size of D; the aDataSize argument of BTraceBig + - X is the maximum number of additional bytes which will fit into a trace record. + This is usually KMaxBTraceDataArray but this should not be assumed, instead + the size and other information present in each trace record should be examined. + + For the first part of a multipart trace, the data in a trace record has the following + structure: + - 4 bytes containing N. + - 4 bytes containing A. + - X bytes containing D[0..X-1] + + If the parts are numbered 0 through to 'j', then a middle part of a multipart trace + is numbered 'i' where 0 0); + assert(aEntry != BTrace::ERecordTruncated); + assert(aEntry != BTrace::EMissingRecord); + + int offset = 4; // size, flags, 1ry category, subcategory + unsigned char mask = aEntry - 1; + mask &= ~(BTrace::ERecordTruncated | BTrace::EMissingRecord); + + unsigned char n = Flags() & mask; + while (n) + { + offset += ((n & 1UL) * 4) ; + n >>= 1 ; + } + + return offset; + } + + +void CUTraceFrame::DumpFlags(std::ostream& aStream) const + { + if (Flags() & BTrace::EHeader2Present) + { + aStream << "Header2Present "; + } + + if (Flags() & BTrace::ETimestampPresent) + { + aStream << "TimestampPresent "; + } + + if (Flags() & BTrace::ETimestamp2Present) + { + aStream << "Timestamp2Present "; + } + + if (Flags() & BTrace::EContextIdPresent) + { + aStream << "ContextIdPresent "; + } + + if (Flags() & BTrace::EPcPresent) + { + aStream << "PcPresent "; + } + + if (Flags() & BTrace::EExtraPresent) + { + aStream << "ExtraPresent "; + } + + if (Flags() & BTrace::ERecordTruncated) + { + aStream << "RecordTruncated "; + } + + if (Flags() & BTrace::EMissingRecord) + { + aStream << "MissingRecord "; + } + } + +void CUTraceFrame::DumpFrame(std::ostream& aStream) const + { + aStream + << "Size: " << std::dec << FrameLength() << std::endl + << "Flags: 0x" << std::noshowbase << std::setw(2) + << std::setfill('0') << std::nouppercase << std::hex + << Flags() << " ("; + + DumpFlags(aStream); + + aStream << ")" << std::endl + << "Primary Filter: 0x" << std::noshowbase << std::setw(2) + << std::setfill('0') << std::nouppercase << std::hex + << PrimaryFilter() << std::endl + << "Subcategory: 0x" << std::noshowbase << std::setw(2) + << std::setfill('0') << std::nouppercase << std::hex + << SubCategory() << std::endl; + + if (Header2Present()) + { + aStream << "Header2: 0x" << std::noshowbase << std::setw(8) + << std::setfill('0') << std::nouppercase << std::hex + << Header2() << std::endl; + } + + if (Timestamp1Present()) + { + aStream << "Timestamp1: " << std::noshowbase << std::dec + << Timestamp1() << std::endl; + } + + if (Timestamp2Present()) + { + aStream << "Timestamp2: " << std::noshowbase << std::dec + << Timestamp2() << std::endl; + } + if (ContextIdPresent()) + { + aStream << "Context Type: "; + switch (ContextType()) + { + case 0: + aStream << "NThread" << std::endl; + aStream << "Context ID: 0x" << std::noshowbase << std::hex << std::nouppercase + << std::setw(8) << std::setfill('0') << ContextId() << std::endl; + break; + + case 1: + aStream << "Fast Interrupt (FIQ)" << std::endl; + break; + + case 2: + aStream << "Interrupt (IRQ)" << std::endl; + break; + + case 3: + aStream << "Immediate Delayed Function Call (IDFC)" << std::endl; + break; + } + } + + if (PcPresent()) + { + aStream << "PC: 0x" << std::noshowbase << std::setw(8) + << std::setfill('0') << std::nouppercase << std::hex + << ProgramCounter() << std::endl; + } + + if (IsMultiPart()) + { + aStream << "Multipart Frame: "; + switch (Header2() & BTrace::EMultiPartFlagMask) + { + case 1: + aStream << "EMultiPartFirst"; + break; + + case 2: + aStream << "EMultiPartMiddle"; + break; + + case 3: + aStream << "EMultiPartLast"; + break; + } + aStream << std::endl; + } + + if (ExtraPresent()) + { + if (IsMultiPart()) + { + aStream << "MultiPart Event Id: 0x"; + } + else + { + aStream << "Extra: 0x"; + } + + aStream << std::noshowbase << std::setw(8) + << std::setfill('0') << std::nouppercase << std::hex + << Extra() << std::endl; + } + + if (!IsMultiPart() || MultiPartType() == BTrace::EMultiPartFirst) + { + aStream << "Arg1: 0x" << std::noshowbase << std::setw(8) + << std::setfill('0') << std::nouppercase << std::hex + << Arg1() << std::endl; + } + + unsigned int zones[1] = { (unsigned int)(Data() - iFrameBuffer) }; + DumpBytes(aStream, iFrameBuffer, FrameLength(), zones, 1); + aStream << std::endl; + aStream.flush(); + } + + +void CUTraceFrame::DumpFrame(std::string& aOutput) const + { + std::ostringstream ss; + DumpFrame(ss); + aOutput += ss.str(); + } + + +CMultiPartFrameCollection::CMultiPartFrameCollection(CUTraceFrame* aFrame) + { + assert(aFrame->IsMultiPart()); + push_back(aFrame); + } + +CMultiPartFrameCollection::~CMultiPartFrameCollection() + { + while (!empty()) + { + CUTraceFrame* frame = this->back(); + this->pop_back(); + delete frame; + } + } + +void CMultiPartFrameCollection::AddFrame(CUTraceFrame* aFrame) + { + assert(aFrame->IsMultiPart() && aFrame->MultiPartSequenceNumber() == MultiPartId()); + push_back(aFrame); + } + +unsigned int CMultiPartFrameCollection::MultiPartId() const + { + return at(0)->MultiPartSequenceNumber(); + } +