Update contrib.
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\debug\d_logtofile.cpp
15 // d_logtofile.ldd is kernel side of t_logtofile application that tests *
16 // trace handler hook (TTraceHandler). See t_logtofile.cpp for details. *
20 #include "d_logtofile.h"
21 #include <kernel/kern_priv.h>
23 _LIT(PatternInfo, "Pattern:");
24 _LIT(BufferInfo, "Buffer Size:");
25 _LIT(FastCounterInfo, "Fast couner freq:");
26 const TInt MaxLogSize=300;
27 ///////////////////////////////////////////////////////////////////////
28 class DLogToFile : public DLogicalChannelBase
33 static TBool Handler (const TDesC8& aText, TTraceSource aTraceSource);
35 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
36 virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
44 DChunk* iChunk; /**Shared chunk*/
45 TLinAddr iChunkKernelAddr; /**Kernel base address of the chunk*/
46 TUint32 iChunkMapAttr; /**Mapping attributes of the chunk*/
47 TBool iBufferFull; /**Chunk full indication*/
48 TText8* iCurrent; /**Current pointer to the chunk space*/
49 TChunkCreateStr iChunkCreateStr;/**Input arguments(matching pattern and the chunk size) from user side*/
50 TTraceHandler iOldHook; /**Previous trace logging hook*/
55 DLogToFile::DLogToFile()
59 DLogToFile::~DLogToFile()
66 Should be able to run in any content (including ISR).
67 @return EFalse, always and that way suppresses debug logging to serial port.
69 TBool DLogToFile::Handler (const TDesC8& aText, TTraceSource aTraceSource)
71 if(Logger->iBufferFull)
74 TInt irq=NKern::DisableAllInterrupts(); //Disable interrupts to prevent loggings overlapping each other.
76 if (aText.Length() < Logger->iChunkCreateStr.iPattern.Length())
78 NKern::RestoreInterrupts(irq);
79 return ETrue; //The log is too short to match the pattern
81 TPtrC8 ptr( aText.Ptr(), Logger->iChunkCreateStr.iPattern.Length());
82 if (ptr != Logger->iChunkCreateStr.iPattern) //Compare the pattern against the start of the log
84 NKern::RestoreInterrupts(irq);
85 return ETrue; //Does not match
89 fcBuffer.AppendNum(NKern::FastCounter());//If it was a real tool, we should not do this here.
91 memcpy (Logger->iCurrent, fcBuffer.Ptr(), fcBuffer.Length());
92 Logger->iCurrent+=fcBuffer.Length();
93 *(Logger->iCurrent++) = '\t';
99 *(Logger->iCurrent++) = 'K';
100 *(Logger->iCurrent++) = '\t';
101 memcpy (Logger->iCurrent, aText.Ptr(),aText.Length());
107 *(Logger->iCurrent++) = 'P';
108 *(Logger->iCurrent++) = '\t';
109 //PlatSec log could be of any size. Additional checking required:
110 if ((TInt)Logger->iCurrent > (TInt)(Logger->iChunkKernelAddr + Logger->iChunkCreateStr.iSize - aText.Length()))
112 Logger->iBufferFull = ETrue;
115 memcpy (Logger->iCurrent, aText.Ptr(),aText.Length());
121 *(Logger->iCurrent++) = 'U';
122 *(Logger->iCurrent++) = '\t';
123 memcpy(Logger->iCurrent, aText.Ptr(),aText.Length());
131 Logger->iCurrent+=aText.Length();
132 *(Logger->iCurrent++) = '\n';
134 if ((TInt)Logger->iCurrent > (TInt)(Logger->iChunkKernelAddr + Logger->iChunkCreateStr.iSize - MaxLogSize))
135 Logger->iBufferFull = ETrue;
137 NKern::RestoreInterrupts(irq);
145 TInt DLogToFile::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
151 Creates chunk and opens another chunk handle for user side.
152 Returns user side handle.
154 TInt DLogToFile::CreateChunk()
157 TChunkCreateInfo info;
158 info.iType = TChunkCreateInfo::ESharedKernelSingle;
159 info.iMaxSize = iChunkCreateStr.iSize;//This is hard coded to 64K. No need to round to page size.
161 info.iMapAttr = (TInt)EMapAttrFullyBlocking; // Full caching
163 info.iOwnsMemory = ETrue; // Use memory from system's free pool
164 info.iDestroyedDfc = NULL;
166 NKern::ThreadEnterCS();
167 if (KErrNone != (r = Kern::ChunkCreate(info, iChunk, iChunkKernelAddr, iChunkMapAttr)))
169 NKern::ThreadLeaveCS();
172 r = Kern::ChunkCommit(iChunk,0,iChunkCreateStr.iSize);
175 Kern::ChunkClose(iChunk);
176 NKern::ThreadLeaveCS();
179 r = Kern::MakeHandleAndOpen(NULL, iChunk);
182 Kern::ChunkClose(iChunk);
183 NKern::ThreadLeaveCS();
186 NKern::ThreadLeaveCS();
187 iCurrent = (TText8*)iChunkKernelAddr;
193 Logs input parameters info into chunk and starts logging.
195 void DLogToFile::Start()
198 memcpy (Logger->iCurrent, ((const TDesC&)PatternInfo).Ptr(), ((const TDesC&)PatternInfo).Length());
199 iCurrent+=((const TDesC&)PatternInfo).Length();
200 *(Logger->iCurrent++) = '\t';
201 memcpy (Logger->iCurrent, iChunkCreateStr.iPattern.Ptr(), iChunkCreateStr.iPattern.Length());
202 Logger->iCurrent += iChunkCreateStr.iPattern.Length();
203 *(iCurrent++) = '\n';
206 memcpy (iCurrent, ((const TDesC&)BufferInfo).Ptr(), ((const TDesC&)BufferInfo).Length());
207 iCurrent+=((const TDesC&)BufferInfo).Length();
208 *(Logger->iCurrent++) = '\t';
210 buf.AppendNum(iChunkCreateStr.iSize);
211 memcpy (iCurrent, buf.Ptr(), buf.Length());
212 iCurrent+=buf.Length();
213 *(iCurrent++) = '\n';
215 //Log fast counter info
216 memcpy (iCurrent, ((const TDesC&)FastCounterInfo).Ptr(), ((const TDesC&)FastCounterInfo).Length());
217 iCurrent+=((const TDesC&)FastCounterInfo).Length();
218 *(iCurrent++) = '\t';
220 buf.AppendNum(NKern::FastCounterFrequency());
221 memcpy (iCurrent, buf.Ptr(), buf.Length());
222 iCurrent+=buf.Length();
223 *(iCurrent++) = '\n';
226 iOldHook = Kern::SetTraceHandler(DLogToFile::Handler);
230 Stops logging into chunk. Returns the size of the log.
232 TInt DLogToFile::Stop()
234 //Setting the old hook is always risky. Is the old hook still valid?
235 //We'll do it for the sake of testing.
236 Kern::SetTraceHandler(iOldHook);
237 return (TInt)Logger->iCurrent - Logger->iChunkKernelAddr;
241 Closes the shared chunk
243 void DLogToFile::RemoveChunk()
245 NKern::ThreadEnterCS();
246 //It has been a while since we removed the hook. It should be safe to close the chunk now.
247 Kern::ChunkClose(iChunk);
248 NKern::ThreadLeaveCS();
252 User side request entry point.
254 TInt DLogToFile::Request(TInt aFunction, TAny* a1, TAny* /*a2*/)
259 case RLogToFileDevice::EControlCreateChunk:
261 kumemget(&iChunkCreateStr, a1,sizeof(TChunkCreateStr));
265 case RLogToFileDevice::EControlStart:
270 case RLogToFileDevice::EControlStop:
275 case RLogToFileDevice::EControlRemoveChunk:
287 //////////////////////////////////////////
288 class DTestFactory : public DLogicalDevice
292 // from DLogicalDevice
293 virtual TInt Install();
294 virtual void GetCaps(TDes8& aDes) const;
295 virtual TInt Create(DLogicalChannelBase*& aChannel);
298 DTestFactory::DTestFactory()
300 iParseMask = KDeviceAllowUnit;
304 TInt DTestFactory::Create(DLogicalChannelBase*& aChannel)
306 Logger = new DLogToFile;
308 return (aChannel ? KErrNone : KErrNoMemory);
311 TInt DTestFactory::Install()
313 return SetName(&KLogToFileName);
316 void DTestFactory::GetCaps(TDes8& /*aDes*/) const
320 DECLARE_STANDARD_LDD()
322 return new DTestFactory;