diff -r a151135b0cf9 -r aa2539c91954 tracesrv/tracecore/btrace_handler/test/d_tracecore/src/d_tracecore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tracesrv/tracecore/btrace_handler/test/d_tracecore/src/d_tracecore.cpp Fri Oct 08 14:56:39 2010 +0300 @@ -0,0 +1,508 @@ +// Copyright (c) 2005-2010 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: +// e32test\debug\d_tracecore.cpp +// +// + +#include +#include + +#include +#include + +#ifndef __SMP__ +#include +#else +#include +#endif //__SMP__ +#include +#include +#include "TraceCore.h" +#include "d_tracecore.h" + + +#include "TraceCoreTestWriter.h" +#include "TestDataWriterNotifier.h" + +const TInt KFrameBufferLength = 4096; + +class DTraceCoreTestFactory : public DLogicalDevice + { +public: + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); + }; + +class DTraceCoreTestChannel : public DLogicalChannel, MTestWriterNotifier, MTraceCoreNotificationReceiver + { +public: + DTraceCoreTestChannel(); + virtual ~DTraceCoreTestChannel(); + // Inherited from DObject + virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType); + // Inherited from DLogicalChannelBase + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual void HandleMsg(TMessageBase* aMsg); + TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); + TInt DoRequest(TInt aId, TRequestStatus* aStatus, TAny* a1, TAny* a2); + + // Virtual from MTraceCoreNotificationReceiver. Called from TraceCore. + void TraceActivated( TUint32 aComponentId, TUint16 aGroupId ); + void TraceDeactivated( TUint32 aComponentId, TUint16 aGroupId ); + + +private: + DThread* iClient; + +private: + void ActivateTrace(TcDriverParameters& aDriverParameters, TInt aNumTraces); + void DeactivateTrace(TcDriverParameters& aDriverParameters, TInt aNumTraces); + TInt RefreshActivations(); + TInt ValidateFilterSync(TcDriverParameters& aDriverParams); + void DropNextTrace(TBool aDrop); + void RegisterActivationNotification(TcDriverParameters& aDriverParameters, TBool aRegister); + TInt CheckActivationNotificationOk(TBool aShouldBeNotified); + + TInt CreateWriter(); + // from MTestWriterNotifier + virtual void WriteComplete(TNotifyData aData); + virtual void WriteStart(); +private: + + TRequestStatus* iTraceDataRequestStatus; // request status for asynct trace requests + TDes8* iTraceDataDestination; // pointer to write trace data to + TDynamicDfcQue* iOstTestDriverDfcQ; // Dedicated non-realtime DfcQ + TBool iDropTrace; // if test doesn't want trace to actually be sent + TInt iFrameCount; // Number of frames to capture before notify is issued + TBuf8 iFrameBuffer; // the frame buffer + TBool iFilterInSyncWhenNotified; // If true, filter in TraceCore was in sync with the notification + TBool iNotificationReceived; // If true, trace activation notification was received + }; + +const TInt KTestOstDriverThreadPriority = 24; +_LIT(KTestOstDriverThread,"d_tracecore_dfcq"); + + +// +// DTraceCoreTestFactory +// + +TInt DTraceCoreTestFactory::Install() + { + return SetName(&RTraceCoreTest::Name()); + } + +void DTraceCoreTestFactory::GetCaps(TDes8& aDes) const + { + Kern::InfoCopy(aDes,0,0); + } + +TInt DTraceCoreTestFactory::Create(DLogicalChannelBase*& aChannel) + { + aChannel=new DTraceCoreTestChannel(); + if(!aChannel) + return KErrNoMemory; + return KErrNone; + } + + +// +// DTraceCoreTestChannel +// + +DTraceCoreTestChannel::DTraceCoreTestChannel() +: iTraceDataRequestStatus(NULL) +, iTraceDataDestination(NULL) +, iDropTrace(EFalse) +, iFilterInSyncWhenNotified(EFalse) + { + } + +DTraceCoreTestChannel::~DTraceCoreTestChannel() + { + // Detatch (stop notifications) from writer + DTraceCoreTestWriter* testWriter = DTraceCoreTestWriter::GetInstance(); + if(testWriter) + { + testWriter->SetNotifier(NULL); + } + delete testWriter; + + //destroy dfcq + if (iOstTestDriverDfcQ) + { + iOstTestDriverDfcQ->Destroy(); + } + } + +TInt DTraceCoreTestChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) + { + TDynamicDfcQue* q; + TInt ret = Kern::DynamicDfcQCreate(q, KTestOstDriverThreadPriority , KTestOstDriverThread); + if (ret==KErrNone) + { + //disable real-time state of the dfcq + q->SetRealtimeState(ERealtimeStateOff); + iOstTestDriverDfcQ=q; + SetDfcQ(iOstTestDriverDfcQ); + iMsgQ.Receive(); + } + else + { + Kern::Printf("Kern::DynamicDfcQCreate returned with error: %d",ret); + return ret; + } + iClient = &Kern::CurrentThread(); + return CreateWriter(); + } + +void DTraceCoreTestChannel::WriteStart() + { + } + +void DTraceCoreTestChannel::WriteComplete(TNotifyData aNotifyData) + { + + if(iTraceDataRequestStatus && iFrameCount > 0 ) + { + + // append the data into the frame buffer if it fits + if( iFrameBuffer.Length() + aNotifyData.iLen < KFrameBufferLength) + { + iFrameBuffer.Append(TPtrC8((TUint8*)aNotifyData.iAddr, aNotifyData.iLen )); + } + else + { + // force a send of what we have + iFrameCount = 1; + } + + if( --iFrameCount == 0) + { + if (iDropTrace) + { + // test client is requesting we force tracecore to drop the next trace + // so we call the same function that a writer would call ( SetPreviousTraceDropped ) + // in order to notify tracecore that a trace has been dropped + DTraceCore* tracecore = DTraceCore::GetInstance(); + tracecore->SetPreviousTraceDropped(ETrue); + } + else//send the trace + { + Kern::KUDesPut(*iTraceDataDestination,iFrameBuffer); + } + + // complete the clients request + Kern::RequestComplete(iTraceDataRequestStatus, 0); + iTraceDataRequestStatus = NULL; + iFrameBuffer.Zero(); + } + } + } + +TInt DTraceCoreTestChannel::CreateWriter() + { + TInt r = KErrNoMemory; + DTraceCoreTestWriter* testWriter = DTraceCoreTestWriter::GetInstance(); + if(testWriter) + { + r = KErrNone; + testWriter->SetNotifier(this); + } + return r; + } + +TInt DTraceCoreTestChannel::RequestUserHandle(DThread* aThread, TOwnerType aType) + { + if (aType!=EOwnerThread || aThread!=iClient) + return KErrAccessDenied; + return KErrNone; + } + +void DTraceCoreTestChannel::HandleMsg(TMessageBase* aMsg) + { + TThreadMessage& msg = *(static_cast(aMsg)); + TInt id = msg.iValue; + + if ( id == static_cast( ECloseMsg ) ) + { + + // Don't receive any more messages + msg.Complete( KErrNone, EFalse ); + + // Complete all outstanding messages on this queue + iMsgQ.CompleteAll( KErrServerTerminated ); + } + else if ( id == KMaxTInt ) + { + // 'DoCancel' message + TRequestStatus* pS = reinterpret_cast( msg.Ptr0() ); + Kern::RequestComplete(iClient,pS,KErrCancel); + msg.Complete( KErrNone, ETrue ); + } + else if ( id < 0 ) + { + // DoRequest + TRequestStatus* pS = reinterpret_cast( msg.Ptr0() ); + + TInt ret = DoRequest( ~id, pS, msg.Ptr1(), msg.Ptr2()); + if ( ret != KErrNone ) + { + Kern::RequestComplete( iClient, pS, ret ); + }//noelse + + msg.Complete( KErrNone, ETrue ); + } + else + { + // DoControl + TInt ret = DoControl( id, msg.Ptr0(), msg.Ptr1() ); + msg.Complete( ret, ETrue ); + } + + } + +TInt DTraceCoreTestChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2) + { + switch(aFunction) + { + // test functions + case RTraceCoreTest::EActivateTrace: + { +// Kern::Printf("DTraceCoreTestChannel::DoControl() RTraceCoreTest::EActivateTrace"); + TcDriverParameters* tcDriverParameters = static_cast(a1); + __ASSERT_ALWAYS(tcDriverParameters!=NULL, Kern::Fault("DTraceCoreTestChannel::DoControl: NULL parameter!", __LINE__) ); + ActivateTrace(*tcDriverParameters, (TInt)(a2)); + return KErrNone; + } + case RTraceCoreTest::EDeactivateTrace: + { +// Kern::Printf("DTraceCoreTestChannel::DoControl() RTraceCoreTest::EDeactivateTrace"); + TcDriverParameters* tcDriverParameters = static_cast(a1); + __ASSERT_ALWAYS(tcDriverParameters!=NULL, Kern::Fault("DTraceCoreTestChannel::DoControl: NULL parameter!", __LINE__) ); + DeactivateTrace(*tcDriverParameters, (TInt)(a2)); + return KErrNone; + } + case RTraceCoreTest::ERefreshActivations: + { +// Kern::Printf("DTraceCoreTestChannel::DoControl() RTraceCoreTest::ERefreshActivations"); + return RefreshActivations(); + } + + case RTraceCoreTest::EValidateFilterSync: + { +// Kern::Printf("DTraceCoreTestChannel::ReqDoControluest() RTraceCoreTest::EValidateFilterSync"); + TcDriverParameters* tcDriverParameters = static_cast(a1); + __ASSERT_ALWAYS(tcDriverParameters!=NULL, Kern::Fault("DTraceCoreTestChannel::DoControl: NULL parameter!", __LINE__) ); + return ValidateFilterSync(*tcDriverParameters); + } + + case RTraceCoreTest::EDropNextTrace: + { +// Kern::Printf("DTraceCoreTestChannel::DoControl() RTraceCoreTest::EDropNextTrace"); + DropNextTrace(TBool(a1)); + return KErrNone; + } + case RTraceCoreTest::ERegisterActivationNotification: + { +// Kern::Printf("DTraceCoreTestChannel::DoControl() RTraceCoreTest::ERegisterActivationNotification"); + TcDriverParameters* tcDriverParameters = static_cast(a1); + __ASSERT_ALWAYS(tcDriverParameters!=NULL, Kern::Fault("DTraceCoreTestChannel::DoControl: NULL parameter!", __LINE__) ); + RegisterActivationNotification(*tcDriverParameters, (TBool)(a2)); + return KErrNone; + } + case RTraceCoreTest::ECheckActivationNotificationOk: + { +// Kern::Printf("DTraceCoreTestChannel::DoControl() RTraceCoreTest::ECheckActivationNotificationOk"); + return CheckActivationNotificationOk((TBool)(a1)); + } + + default: + break; + } + return KErrNotSupported; + } + +TInt DTraceCoreTestChannel::DoRequest(TInt aId, TRequestStatus* aStatus, TAny* a1, TAny* a2) + { + switch(aId) + { + case RTraceCoreTest::ERequestTraceData: // async request + { + iTraceDataRequestStatus = aStatus; + if(a1) + { + TDes8* p = NULL; + XTRAPD(r, XT_DEFAULT, kumemget(&p, &a1, sizeof(TAny*)); ) + iTraceDataDestination = (r == KErrNone) ? p : NULL; + } + + iFrameCount = (a2) ? (TInt)a2 : 1; + iFrameBuffer.Zero(); + + return KErrNone; + } + + default: + break; + } + return KErrNotSupported; + } + +void DTraceCoreTestChannel::ActivateTrace(TcDriverParameters& aDriverParameters, TInt aNumTraces) + { + TcDriverParameters tcDriverParams; + TInt ret = Kern::ThreadRawRead(iClient, (const TAny *)&aDriverParameters,(TAny*)&tcDriverParams, sizeof(TcDriverParameters) ); + __ASSERT_ALWAYS(KErrDied!=ret, Kern::Fault("DTraceCoreTestChannel::ActivateTrace: ThreadRawRead: iClient died!", __LINE__) ); + + NKern::ThreadEnterCS(); + for (TInt i=0; i