--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/debug/crashMonitor/inc/scmdatatypes.h Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,722 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// Definitions for the data types the SCM stores to flash
+//
+// WARNING: This file contains some APIs which are internal and are subject
+// to change without notice. Such APIs should therefore not be used
+// outside the Kernel and Hardware Services package.
+//
+
+
+#ifndef __SCMDATATYPES_H_INCLUDED__
+#define __SCMDATATYPES_H_INCLUDED__
+
+#include <rm_debug_api.h>
+#include <e32rom.h>
+
+#include <scmbytestreamutil.h>
+#include <scmtrace.h>
+
+/**
+ @file
+ @internalComponent
+ */
+
+namespace Debug
+{
+ /** SCM Data Types Major Number */
+ static const TInt KSCMDataTypesMajorVersion = 1;
+
+ /** SCM Data Types Minor Number */
+ static const TInt KSCMDataTypesMinorVersion = 0;
+
+ /** SCM Data Types Build Number */
+ static const TInt KSCMDataTypesBuildNumber = 0;
+
+ /**
+ * This enum defines the type of struct we are dealing with when we
+ * are serialising/deserialising
+ */
+ enum SCMStructId
+ {
+ ESCMFirst,
+ ESCMOffsetsHeader,
+ ESCMTCrashInfo,
+ ESCMProcessData,
+ ESCMThreadData,
+ ESCMThreadStack,
+ ESCMRegisterValue,
+ ESCMRegisterSet,
+ ESCMMemory,
+ ESCMCodeSegSet,
+ ESCMCodeSeg,
+ ESCMRawData,
+ ESCMTraceData,
+ ESCMLocks,
+ ESCMKernelHeap,
+ ESCMVariantData,
+ ESCMRomHeader,
+ ESCMLast
+ };
+
+ /**
+ * This class represents the header at the start of a crash log
+ * describing the size of the crash log and minimal location
+ * information
+ */
+ class TCrashOffsetsHeader : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMCrashOffsetsMaxSize = 20 * sizeof(TUint32) + sizeof(TUint16);
+
+ enum TCrashHeaderVersion
+ {
+ EChVersion1 = 1
+ };
+
+ TCrashOffsetsHeader();
+
+ //From MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ TBool operator == (const TCrashOffsetsHeader& aOther) const;
+
+ SCMStructId iId;
+ TCrashHeaderVersion iVersion;
+
+ //These next members are offsets to the crash data in the log
+ TUint32 iCTFullRegOffset;
+ TUint32 iCTUsrStkOffset;
+ TUint32 iCTSvrStkOffset;
+ TUint32 iCPMetaOffset;
+ TUint32 iCTMetaOffset;
+ TUint32 iCPCodeSegOffset;
+ TUint32 iSysUsrStkOffset;
+ TUint32 iSysSvrStkOffset;
+ TUint32 iSysUsrRegOffset;
+ TUint32 iSysSvrRegOffset;
+ TUint32 iTLstOffset;
+ TUint32 iPLstOffset;
+ TUint32 iSysCodeSegOffset;
+ TUint32 iExcStkOffset;
+ TUint32 iTraceOffset;
+ TUint32 iScmLocksOffset;
+ TUint32 iKernelHeapOffset;
+ TUint32 iVarSpecInfOffset;
+ TUint32 iRomInfoOffset;
+
+ TUint32 iSpare1;
+ TUint32 iSpare2;
+ TUint32 iSpare3;
+ TUint32 iSpare4;
+ TUint32 iSpare5;
+ TUint32 iSpare6;
+
+ };
+
+ /**
+ * This class stores meta data for a given crash
+ */
+ class TCrashInfoHeader : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KMaxCatSize = 80;
+ static const TInt KSCMCrashInfoMaxSize = 76 + KMaxCatSize;
+
+ enum TCrashInfoHeaderVersion { ECiVersion1 = 1 };
+ TCrashInfoHeader();
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ TBool operator == (const TCrashInfoHeader& aOther) const;
+
+
+ SCMStructId iId;
+ TCrashInfoHeaderVersion iVersion;
+ TInt32 iLogSize;
+ TInt32 iFlashAlign;
+ TInt32 iCachedWriterSize;
+ TUint64 iPid;
+ TUint64 iTid;
+ TInt32 iExitType;
+ TInt32 iExitReason;
+ TInt32 iExcCode;
+ TInt64 iCrashTime;
+ TInt32 iCrashId;
+ TInt32 iFlashBlockSize;
+ TInt32 iFlashPartitionSize;
+ TVersion iSCMDataTypesVersion;
+ TUint32 iCategorySize;
+ TBuf8<KMaxCatSize> iCategory;
+
+ TInt32 iSpare1;
+ TInt32 iSpare2;
+ };
+
+ /**
+ * This class is used for a raw memory dump. It will always be preceded by a TMemoryDump.
+ *
+ * Note: This class contains a TPtr8 to store the data
+ * name. Due to us not being able to allocate memory when the system
+ * is down, we assume that the memory to which this points is owned
+ * by someone else. It is constructed to point to NULL. To make use
+ * of this, before serialising the data, ensure to set it to point to
+ * the location required. Equally, when derserialising, ensure to allocate
+ * a descriptor of required bytes (determined from TMemoryDump) and set it to iData, otherwise
+ * the name will be ignored upon reading.
+ */
+ class TRawData : public MByteStreamSerializable
+ {
+ public:
+
+ //Note this doesnt include the data, as this number is not determinable
+ static const TInt KSCMRawDataMaxSize = 2 * sizeof(TUint32) + sizeof(TUint16);
+
+ enum TTRawDataVersion { ETRawData1 = 1 };
+ TRawData();
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ TInt Deserialize(TInt aStartPos, TByteStreamReader& aReader);
+
+ SCMStructId iId;
+ TTRawDataVersion iVersion;
+
+ TInt32 iLength;
+ TPtr8 iData;
+
+ };
+
+ /**
+ * This class stores meta data for a given process
+ */
+ class TProcessData : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMProcessDataMaxSize = sizeof(TUint16) + sizeof(TUint64) + 2 * sizeof(TUint32) + KMaxProcessName;
+
+ enum TProcessDataVersion { EProcData1 = 1 };
+ TProcessData();
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ SCMStructId iId;
+ TProcessDataVersion iVersion;
+
+ TUint64 iPid;
+ TUint32 iNamesize; //Length of process filename in bytes
+ TInt32 iPriority;
+
+ TBuf8<KMaxProcessName> iName;
+
+ TInt32 iSpare1;
+ TInt32 iSpare2;
+ TInt32 iSpare3;
+ };
+
+ /**
+ * This class stores meta data for a given thread
+ */
+ class TThreadData : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KMaxThreadName = KMaxProcessName;
+ static const TInt KSCMThreadDataMaxSize = sizeof(TUint32) + sizeof(TUint16) + 11 * sizeof(TUint32) + 2 * sizeof(TUint64) + KMaxThreadName;
+
+ enum TThreadDataVersion { EThreadData1 = 1 };
+ TThreadData();
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ SCMStructId iId;
+ TInt32 iVersion;
+ TInt32 iPriority;
+ TUint64 iTid;
+ TUint64 iOwnerId;
+ TInt32 iSvcSP;
+ TInt32 iSvcStack;
+ TInt32 iSvcStacksize;
+ TInt32 iUsrSP;
+ TInt32 iUsrStack;
+ TInt32 iUsrStacksize;
+ TUint32 iNamesize;
+ TUint32 iLastCpu;
+ TInt32 iSvcHeap;
+ TInt32 iSvcHeapSize;
+
+ TBuf8<KMaxThreadName> iName;
+
+ TInt32 iSpare1;
+ TInt32 iSpare2;
+ };
+
+ /**
+ * This class stores the stack for a given thread. The type (user or supervisor) is given
+ * by iStackType. It will be followed by a TMemoryDump containing the stack
+ */
+ class TThreadStack : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMThreadStackMaxSize = sizeof(TUint32) + sizeof(TUint16) + 2 * sizeof(TUint32) + sizeof(TUint64);
+
+ enum TThreadStackVersion { EStackVersion1 = 1 };
+
+ enum TThreadStackType
+ {
+ EUsrStack,
+ ESvrStack,
+ EIRQStack,
+ EFIQStack,
+ ELast
+ };
+
+ TThreadStack();
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ SCMStructId iId;
+ TThreadStackVersion iVersion;
+ TThreadStackType iStackType;
+ TUint64 iThreadId;
+ TUint32 iStackSize;
+
+ TInt32 iSpare1;
+ TInt32 iSpare2;
+ };
+
+ /**
+ * Stores the value of a given register and tells you its type
+ */
+ class TRegisterValue : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMRegisterValueMaxSize = sizeof(TUint32) + sizeof(TUint16) + 2 * sizeof(TUint8) + sizeof(TUint16) + sizeof(TUint32) + 2 * sizeof(TUint64);
+
+ TRegisterValue();
+
+ enum TRegisterValueVersion { ERegisterValueVersion1 = 1 };
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ SCMStructId iId;
+ TRegisterValueVersion iVersion;
+ TInt64 iOwnId;
+
+ /**
+ * Same as Sym32_reginfod::rd_id
+ * if rid_class == ESYM_REG_CORE
+ * rd_id is one of rm_debug_api.h::TFunctionalityRegister
+ * else
+ * rd_id is CoProcessor number, eg 15 for ARM CP15
+ */
+ TUint32 iType;
+
+ TUint8 iClass; //Same as Sym32_reginfod::rid_class
+ TUint16 iSubId; //used for coprocessors
+
+ /**
+ * Same as Sym32_reginfod::rd_repre
+ * ESYM_REG_8 == 0,
+ * ESYM_REG_16 == 1,
+ * ESYM_REG_32 == 2,
+ * ESYM_REG_64 == 3
+ */
+ TUint8 iSize; //register size
+
+ // Register value
+ union
+ {
+ // Value of an 8 bit register
+ TUint8 iValue8;
+
+ // Value of a 16 bit register
+ TUint16 iValue16;
+
+ // Value of a 32 bit register
+ TUint32 iValue32;
+
+ // Value of a 64 bit register
+ TUint64 iValue64;
+ };
+
+
+ };
+
+ /**
+ * This class is a header for our register set.
+ */
+ class TRegisterSet : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMRegisterSetMaxSize = sizeof(TUint32) + sizeof(TUint16) + sizeof(TUint32);
+
+ TRegisterSet();
+
+ enum TRegisterSetVersion { ETRegisterSetVersion1 = 1 };
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ TRegisterSetVersion iVersion;
+ SCMStructId iId;
+ TInt32 iNumRegisters;
+ };
+
+ /**
+ * This class describes a memory dump and will be followed by a TRawData
+ */
+ class TMemoryDump : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMMemDumpMaxSize = sizeof(TUint32) + sizeof(TUint16) + 2 * sizeof(TUint32) + sizeof(TUint64);
+
+ enum TMemDumpVersionVersion { EMemDumpVersion1 = 1 };
+
+ TMemoryDump();
+
+ //From MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ SCMStructId iId;
+ TMemDumpVersionVersion iVersion;
+ TUint32 iStartAddress;
+
+ TInt64 iPid;
+ TInt32 iLength;
+ };
+
+ /**
+ * class to represent a set of code segs corrosponding to a given process
+ */
+ class TCodeSegmentSet : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMCodeSegSetMaxSize = KMaxProcessName;
+
+ TCodeSegmentSet();
+
+ enum TCodeSegmentSetVersion { ETCodeSegmentSetVersion1 = 1 };
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ TInt GetMaxSize() const;
+
+ SCMStructId iId; /**< Id that uniquely identifies this data */
+ TCodeSegmentSetVersion iVersion; /**< Version of this data */
+ TInt32 iNumSegs; /**< The number of code segments following this struct that relate to this process ID */
+ TInt64 iPid; /**< Process Id that owns the following code segments */
+ };
+
+ /**
+ * class to represent a code segment in the SCM Log
+ */
+ class TCodeSegment : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KMaxSegmentNameSize = KMaxProcessName;
+
+ //50 is the sum of the size of members that get serialised
+ static const TInt KSCMCodeSegMaxSize = 50 + KMaxSegmentNameSize;
+
+ TCodeSegment();
+
+ enum TCodeSegmentVersion { ETCodeSegmentVersion1 = 1 };
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ TInt GetMaxSize() const;
+
+ SCMStructId iId; /**< Id that uniquely identifies this data */
+ TCodeSegmentVersion iVersion; /**< Version of this data */
+ TCodeSegType iCodeSegType; /**< @see TCodeSegType */
+ TModuleMemoryInfo iCodeSegMemInfo; /**< holds the memory info for this code segment (8 TUint32's)*/
+ TBool iXip; /**< If this code segment is XIP */
+ TInt32 iNameLength; /**< Length of the name of this code segment name */
+ TBuf8<KMaxSegmentNameSize> iName; /**< Name of this code segment */
+
+ };
+
+ /**
+ * This class represents a trace dump in the crash log. It will be immediately followed
+ * in the crash log by a TRawData structure
+ */
+ class TTraceDump : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMTraceDumpMaxSize = sizeof(TUint32) + sizeof(TUint16) + 2 * sizeof(TUint32);
+
+ TTraceDump();
+
+ enum TTraceDumpVersion { ETraceDumpVersion1 = 1 };
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ SCMStructId iId; /**< Id that uniquely identifies this data */
+ TTraceDumpVersion iVersion; /**< Version of this data */
+ TInt32 iSizeOfMemory; /**< Size of the trace data that will be dumped in the following Memory Dump */
+ TInt32 iNumberOfParts; /**< Number of TRawData structs that will follow */
+
+ };
+
+ /**
+ * This represents variant specific data in the crash log. It will be followed
+ * immediately by a TRawData that contains the data
+ */
+ class TVariantSpecificData : public MByteStreamSerializable
+ {
+ public:
+
+ //sizeof(TUint32) + sizeof(TUint16) + sizeof(TUint32)
+ static const TInt KSCMVarSpecMaxSize = 10;
+
+ TVariantSpecificData();
+
+ enum TVariantSpecificDataVersion { EVariantSpecificDataVersion1 = 1 };
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ SCMStructId iId; /**< Id that uniquely identifies this data */
+ TVariantSpecificDataVersion iVersion; /**< Version of this data */
+ TUint32 iSize; /**< Size of the raw data (ie the var spec info) that will follow */
+ };
+
+ /**
+ * This represents the Rom Header Data in the crash Log
+ */
+ class TRomHeaderData : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMRomHdrMaxSize = sizeof(TUint32) + sizeof(TUint16) + sizeof(TUint64) + 2 * sizeof(TUint8) +sizeof(TUint16);
+
+ TRomHeaderData();
+
+ enum TRomHeaderDataVersion { ERomHeaderDataVersion1 = 1 };
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ SCMStructId iId; /**< Id that uniquely identifies this data */
+ TRomHeaderDataVersion iVersion; /**< Version of this data */
+ TUint8 iMajorVersion; /**< Major Version of ROM build */
+ TUint8 iMinorVersion; /**< Minor Version of ROM build */
+ TUint16 iBuildNumber; /**< ROM build number */
+ TUint64 iTime; /**< Build time of ROM in miliseconds */
+ };
+
+ /**
+ * This represents the kernel lock info in the crash log
+ */
+ class TSCMLockData : public MByteStreamSerializable
+ {
+ public:
+
+ static const TInt KSCMLockDataMaxSize = sizeof(TUint32) + 3 * sizeof(TUint16);
+
+ TSCMLockData();
+
+ // from MByteStreamSerializable
+ virtual TInt Serialize(TByteStreamWriter& aWriter);
+ virtual TInt Deserialize(TByteStreamReader& aReader);
+ virtual TInt GetSize() const;
+
+ TInt MutexHoldCount() const;
+ void SetMutexHoldCount(TInt aMutexHoldCount);
+
+ TInt MutexThreadWaitCount() const;
+ void SetMutexThreadWaitCount(TInt aMutexThreadWaitCount);
+
+ TInt LockCount() const;
+ void SetLockCount(TInt aLockCount);
+
+ TBool operator == (const TSCMLockData& aOther) const;
+ TBool operator != (const TSCMLockData& aOther) const;
+
+ private:
+ SCMStructId iId;
+ TInt iMutexHoldCount; // if mutex is valid number of holds on the mutex from current thread
+ TInt iMutexThreadWaitCount; // if mutex is valid number of threads waiting on the mutex
+ TInt iLockCount;
+
+ };
+
+ /**
+ * TScmChecksum class is used to provide a level of sanity checking for the data it processes
+ * the check sum produced is not intended to be computationally unique
+ * This implementation has been chosen as there are restrictions in the data may only be available
+ * in small chunks and the entire data may not be unable to be read (ie comm port implementation)
+ * These restrictions rule out the use of more sophisticated checksums that produce a checksum value for
+ * an entire block of data
+ */
+ class TScmChecksum : MByteStreamSerializable
+ {
+ public:
+ TScmChecksum();
+
+ void ChecksumBlock(const TUint8* aData, TUint aLen);
+ void ChecksumBlock(const TDesC8& aDes);
+ TBool operator == (const TScmChecksum& aOther) const;
+ TBool operator != (const TScmChecksum& aOther) const;
+ void Reset();
+
+ // from MByteStreamSerializable
+ TInt Serialize(TByteStreamWriter& aWriter);
+ TInt Deserialize(TByteStreamReader& aReader);
+ TInt GetSize() const;
+
+ private:
+ /** Total length of all data in bytes*/
+ TUint32 iLength;
+ /** Sum of all bytes*/
+ TUint32 iSum;
+ /** Count of Bytes with value 0*/
+ TUint32 iZeroCount;
+
+ };
+
+ /** class to describe a flash block */
+ class SCMCrashBlockEntry
+ {
+ public:
+
+ SCMCrashBlockEntry()
+ : iBlockNumber(0)
+ , iBlockOffset(0)
+ , iBlockSize(0)
+ , iNext(NULL)
+ {
+
+ }
+
+ SCMCrashBlockEntry(TInt aBlockNumber, TInt aBlockOffset, TInt aBlockSize)
+ : iBlockNumber(aBlockNumber)
+ , iBlockOffset(aBlockOffset)
+ , iBlockSize(aBlockSize)
+ , iNext(NULL)
+ {
+
+ }
+
+ /** The offset in bytes to this block from start of flash*/
+ TInt iBlockNumber;
+ /** The offset in bytes to this block from start of flash*/
+ TInt iBlockOffset;
+ /** the size of the flash block in bytes */
+ TInt iBlockSize;
+ /** pointer to next in list*/
+ SCMCrashBlockEntry* iNext;
+
+ };
+
+ /** Because of limitations in flash memory driver available to the
+ * system crash monitor - this class is used to describe the locations
+ * on flash where crashes will be stored
+ * we store 1 crash per block of flash ! This eliminates the
+ * need to for the scmonitor to hold memory required for bufering write data to flash
+ * class used to describe locations (typically in flash)
+ * where
+ * holds a linked list of SCMCrashBlockEntry which describe an area we can write to
+ */
+ class SCMMultiCrashInfo
+ {
+ public:
+
+ /** constructor */
+ SCMMultiCrashInfo();
+
+ /** destructor */
+ ~SCMMultiCrashInfo();
+
+ /** add a pointer to a block to the list - takes ownership of block */
+ void AddBlock(SCMCrashBlockEntry* aBlockEntry);
+
+ /** GetNextBlock returns NULL when no more blocks */
+ SCMCrashBlockEntry* GetNextBlock();
+
+ /** sets current block to first in list */
+ void Reset();
+
+ /** clear all entries in the list */
+ void ClearList();
+
+
+ private:
+ SCMCrashBlockEntry* iFirstBlock;
+ SCMCrashBlockEntry* iCurrentBlock;
+ TInt iSpare;
+ };
+
+ /**
+ * This constant gives us the maximum size of the Core Crash Header which consists of the Crash Info, the Offsets
+ * Header and the Core Registers
+ */
+ static const TInt KMaxCoreHeaderSize = TCrashInfoHeader::KSCMCrashInfoMaxSize //Crash Info - always there
+ + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize //offsets header - optional
+ + TRegisterSet::KSCMRegisterSetMaxSize //The crash context - always there
+ + TRegisterValue::KSCMRegisterValueMaxSize * 37; //could be up to 37 register values
+
+ }
+
+#endif //__SCMDATATYPES_H_INCLUDED__
+
+//eof scmdatatypes.h