tracesrv/tracecore/btrace_handler/test/d_traceonactivation/src/TraceOnActivation.cpp
changeset 56 aa2539c91954
equal deleted inserted replaced
54:a151135b0cf9 56:aa2539c91954
       
     1 // Copyright (c) 2007-2010 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 "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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <kernel/arm/assp.h>
       
    17 #include <kernel/kernel.h>
       
    18 #include <TraceCoreCommon.h>
       
    19 
       
    20 #include "TraceCore.h"
       
    21 #include "TraceCoreConstants.h"
       
    22 #include "TraceOnActivation.h"
       
    23 #include "TraceOnActivationIf.h"
       
    24 #include "TraceConnection.h"
       
    25 
       
    26 
       
    27 //===========================================================================
       
    28 // DTcFactory Class
       
    29 //===========================================================================
       
    30 
       
    31 //---------------------------------------------------------------------------
       
    32 /**
       
    33     DTcFactory Constructor
       
    34 */
       
    35 DTcFactory::DTcFactory()
       
    36 : DLogicalDevice()
       
    37     {
       
    38     // The version of this logical device
       
    39     iVersion = TVersion( RTraceOnActivation::EMajorVersionNumber,
       
    40                          RTraceOnActivation::EMinorVersionNumber,
       
    41                          RTraceOnActivation::EBuildVersionNumber );
       
    42 
       
    43     // A bitmasks that indicates device properties
       
    44     iParseMask = 0;
       
    45     iUnitsMask = 0;
       
    46     }
       
    47 
       
    48 
       
    49 //---------------------------------------------------------------------------
       
    50 /**
       
    51     DTcFactory Destructor
       
    52 */
       
    53 DTcFactory::~DTcFactory()
       
    54     {
       
    55     }
       
    56 
       
    57 
       
    58 //---------------------------------------------------------------------------
       
    59 /**
       
    60     Completes the installation of this logical device i.e. to do secondary
       
    61     initialization
       
    62 
       
    63     @return KErrNone, if successful
       
    64 */
       
    65 TInt DTcFactory::Install()
       
    66     {
       
    67     return SetName( &KTraceOnActivationDriverName );
       
    68     }
       
    69 
       
    70 
       
    71 //---------------------------------------------------------------------------
       
    72 /**
       
    73     Gets the capabilities of this logical device. Current implementation does
       
    74     nothing.
       
    75 
       
    76     @param  aDes  On return, contains information describing
       
    77                   the capabilities of the device
       
    78 
       
    79 */
       
    80 void DTcFactory::GetCaps(TDes8& /*aDes*/) const
       
    81     {
       
    82     }
       
    83 
       
    84 
       
    85 //---------------------------------------------------------------------------
       
    86 /**
       
    87     Creates a logical channel
       
    88 
       
    89     @param  aChannel Set to point to the created Logical Channel
       
    90 
       
    91     @return KErrNone, if successfull
       
    92 */
       
    93 TInt DTcFactory::Create(DLogicalChannelBase*& aChannel)
       
    94     {
       
    95 	TInt r(KErrNone);
       
    96     aChannel = new DTcChannel( this );
       
    97 
       
    98     if ( aChannel == NULL )
       
    99         {
       
   100         r = KErrNoMemory;
       
   101         }
       
   102 
       
   103     return r;
       
   104     }
       
   105  
       
   106 //===========================================================================
       
   107 // DTcChannel Class
       
   108 //===========================================================================
       
   109 
       
   110 //---------------------------------------------------------------------------
       
   111 /**
       
   112     Constructor
       
   113 
       
   114     @param  aDevice  A pointer to the LDD factory object that
       
   115                     is constructing this logical channel
       
   116 
       
   117 */
       
   118 DTcChannel::DTcChannel(DLogicalDevice* /*aDevice*/)
       
   119         : DLogicalChannel()
       
   120         , iClientThread( NULL )
       
   121         , iActivationQue(NULL)
       
   122     {   
       
   123     }
       
   124 
       
   125 
       
   126 //---------------------------------------------------------------------------
       
   127 
       
   128 /**
       
   129     Destructor
       
   130 */
       
   131 DTcChannel::~DTcChannel()
       
   132     {
       
   133     delete iTraceConnection;
       
   134     iTraceConnection = NULL;
       
   135 
       
   136     // Close our reference on the client thread
       
   137     Kern::SafeClose( reinterpret_cast<DObject*&>( iClientThread ), NULL );
       
   138 
       
   139 #ifdef __SMP_
       
   140     __e32_memory_barrier();
       
   141 #endif
       
   142     }
       
   143 
       
   144 
       
   145 //---------------------------------------------------------------------------
       
   146 /**
       
   147     Completes the outstanding request identified by the specified request
       
   148     number.
       
   149 
       
   150     @param  aMsg  System message from user side
       
   151 */
       
   152 
       
   153 void DTcChannel::HandleMsg(TMessageBase* aMsg)
       
   154     {
       
   155     // Synchronous kernel-side message. There is one per thread, and the
       
   156     // thread always blocks while the message is outstanding.
       
   157     TThreadMessage& msg = *( 
       
   158     				static_cast<TThreadMessage*>( aMsg ) ); 
       
   159     
       
   160     TInt id = msg.iValue;
       
   161 
       
   162     if ( id == static_cast<TInt>( ECloseMsg ) )
       
   163         {
       
   164         // Don't receive any more messages
       
   165         msg.Complete( KErrNone, EFalse );
       
   166 
       
   167         // Complete all outstanding messages on this queue
       
   168         iMsgQ.CompleteAll( KErrServerTerminated );
       
   169         }
       
   170     else
       
   171         {
       
   172         // DoControl
       
   173         TInt ret = DoControl( id, msg.Ptr0() );
       
   174         msg.Complete( ret, ETrue );
       
   175         }
       
   176     }
       
   177 
       
   178 //---------------------------------------------------------------------------
       
   179 /**
       
   180     Performs secondary initialisation of the logical channel
       
   181 
       
   182     @param  aUnit  parameter to the user side handle
       
   183     @param  anInfo  extra information for the device
       
   184     @param  aVer  version requested by the thread
       
   185 
       
   186     @return KErrNone, if succesfull
       
   187 */
       
   188 TInt DTcChannel::DoCreate(TInt aUnit, const  TDesC8* /*anInfo*/,
       
   189                                              const  TVersion& aVer)
       
   190     {
       
   191     // Get pointer to client threads DThread object
       
   192     iClientThread = &Kern::CurrentThread();
       
   193         
       
   194     TInt ret = iClientThread->Open();
       
   195     if(ret != KErrNone)
       
   196         return ret;
       
   197        
       
   198     DTraceCore* tCore = DTraceCore::GetInstance();
       
   199     if(!tCore)
       
   200         return KErrNotReady;
       
   201     iActivationQue = tCore->ActivationQ();
       
   202       
       
   203     // This device driver framework does not apply meaning to the idea of a unit.
       
   204     if ( aUnit != KNullUnit || !iDevice->QueryVersionSupported( aVer ) )
       
   205         {
       
   206         ret = KErrNotSupported;
       
   207         }
       
   208     else
       
   209         {
       
   210         // security check
       
   211         if ( !Kern::CurrentThreadHasCapability( ECapabilityCommDD, 
       
   212                         __PLATSEC_DIAGNOSTIC_STRING("Checked by Tc driver") ) )
       
   213             {
       
   214             ret = KErrPermissionDenied;
       
   215             }
       
   216         if(ret==KErrNone)
       
   217             {
       
   218             iTraceConnection = new DTraceConnection(this);
       
   219             if(!iTraceConnection)
       
   220                 {
       
   221                 ret=KErrNoMemory;
       
   222                 }
       
   223             }
       
   224         if(ret==KErrNone)
       
   225             {
       
   226             // Set the DFC queue to be used by this logical channel to
       
   227             // low priority DFC queue (owned by the TraceCore)
       
   228             SetDfcQ( iActivationQue  );
       
   229             // Mark queue ready to accept messages
       
   230             iMsgQ.Receive();
       
   231             }
       
   232         }
       
   233     
       
   234     return ret;
       
   235     }
       
   236 
       
   237 
       
   238 //---------------------------------------------------------------------------
       
   239 /**
       
   240     Handles a synchronous request
       
   241 
       
   242     @param  aFunction  A number identifying specific functionality
       
   243     @param  a1  If specified, a parameter from the user side
       
   244     @param  a2  If specified, a parameter from the user side
       
   245 
       
   246     @return KErrNone, if successful
       
   247 */
       
   248 TInt DTcChannel::DoControl(TInt aFunction, TAny* a1 = NULL)
       
   249     {
       
   250     TInt ret( KErrNotSupported );
       
   251 
       
   252     switch ( aFunction )
       
   253         {
       
   254         case RTraceOnActivation::ERegisterNotificationReceiver:
       
   255             {
       
   256             ret = RegisterNotificationReceiver( static_cast<TTraceOnActivationParams*>(a1) );
       
   257             break;
       
   258             }
       
   259         case RTraceOnActivation::EUnregisterNotificationReceiver:
       
   260             {
       
   261             ret = UnregisterNotificationReceiver( static_cast<TTraceOnActivationParams*>(a1) );
       
   262             break;
       
   263             }
       
   264         default:
       
   265             break;
       
   266         }
       
   267 
       
   268     return ret;
       
   269     }
       
   270 
       
   271 
       
   272 //---------------------------------------------------------------------------
       
   273 /**
       
   274     Read parameters from user-side thread and call TraceConnection::RegisterNotificationReceiver
       
   275     
       
   276     @param  aParameters Parameters from user-side
       
   277 */
       
   278 TInt DTcChannel::RegisterNotificationReceiver( TTraceOnActivationParams* aParameters )
       
   279     {
       
   280     TTraceOnActivationParams params;
       
   281     TInt ret(KErrNone);
       
   282      //get userside information
       
   283 	ret = Kern::ThreadRawRead(iClientThread, (const TAny *)aParameters,
       
   284 			(TAny*)&params, sizeof(TTraceOnActivationParams) );
       
   285 			
       
   286 	if(ret != KErrNone)
       
   287 	    {
       
   288 	    return ret;
       
   289 	    }
       
   290 			
       
   291     if(iTraceConnection)
       
   292         {
       
   293         // Use correct part of iGroupId
       
   294         params.iGroupId = FixGroupId( params.iGroupId );
       
   295         // Check if iGroupId is valid
       
   296         if (!GroupIdIsValid(params.iGroupId))
       
   297             {
       
   298             ret = KErrArgument;
       
   299             }
       
   300         else
       
   301             {
       
   302             iTraceConnection->RegisterNotificationReceiver( params.iComponentId, params.iGroupId );
       
   303             }
       
   304         }
       
   305     else
       
   306         {
       
   307         ret = KErrGeneral;
       
   308         }
       
   309     
       
   310     return ret;
       
   311     }
       
   312     
       
   313 //---------------------------------------------------------------------------
       
   314 /**
       
   315     Read parameters from user-side thread and call TraceConnection::UnregisterNotificationReceiver
       
   316     
       
   317     @param  aParameters Parameters from user-side
       
   318 */
       
   319 TInt DTcChannel::UnregisterNotificationReceiver( TTraceOnActivationParams* aParameters )
       
   320     {
       
   321     TTraceOnActivationParams params;
       
   322     TInt ret(KErrNone);
       
   323      //get userside information
       
   324 	ret = Kern::ThreadRawRead(iClientThread, (const TAny *)aParameters,
       
   325 			(TAny*)&params, sizeof(TTraceOnActivationParams) );
       
   326 			
       
   327 	if(ret != KErrNone)
       
   328 	    return ret;
       
   329 
       
   330     if(iTraceConnection)
       
   331         {
       
   332         // Use correct part of iGroupId
       
   333         params.iGroupId = FixGroupId( params.iGroupId );
       
   334         // Check if iGroupId is valid
       
   335         if (!GroupIdIsValid(params.iGroupId))
       
   336             {
       
   337             ret = KErrArgument;
       
   338             }
       
   339         else
       
   340             {
       
   341             iTraceConnection->UnregisterNotificationReceiver( params.iComponentId, params.iGroupId );
       
   342             }
       
   343         }
       
   344     else
       
   345         {
       
   346         ret = KErrGeneral;
       
   347         }
       
   348     
       
   349     return ret;
       
   350     }
       
   351 
       
   352 
       
   353 /**
       
   354     TraceActivated Notification
       
   355     
       
   356     Called from TraceConnection-TraceCore
       
   357     
       
   358     @param  aComponentId ComponentId of activated trace
       
   359     @param  aGroupId GroupId of activated trace
       
   360 */
       
   361 TInt DTcChannel::TraceActivated( TUint32 aComponentId, TUint16 aGroupId )
       
   362     {    
       
   363     // Set component ID used in trace point
       
   364     TComponentId KOstTraceComponentID = aComponentId;
       
   365 
       
   366     // Calculate trace word from Group ID
       
   367     TUint32 traceWord = (aGroupId << GROUPIDSHIFT) | 1;
       
   368 
       
   369     // Instrument a trace point, as a simulated priming trace
       
   370     OstTrace0(aGroupId, traceWord, "Priming trace");
       
   371 
       
   372     return KErrNone;
       
   373     }
       
   374 
       
   375 
       
   376 /**
       
   377     TraceDeactivated Notification
       
   378     
       
   379     Called from TraceConnection-TraceCore
       
   380     
       
   381     @param  aComponentId ComponentId of activated trace
       
   382     @param  aGroupId GroupId of activated trace
       
   383     @return 
       
   384 */
       
   385 TInt DTcChannel::TraceDeactivated( TUint32 /*aComponentId*/, TUint16 /*aGroupId*/ )
       
   386     {
       
   387     return KErrNone;
       
   388     }
       
   389 
       
   390 
       
   391 //---------------------------------------------------------------------------
       
   392 /**
       
   393     DECLARE_STANDARD_LDD
       
   394 
       
   395     @return DTcFactory object
       
   396 */
       
   397 DECLARE_STANDARD_LDD()
       
   398     {
       
   399     return new DTcFactory;
       
   400     }
       
   401