diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/driver1__ldd_8cpp-source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/driver1__ldd_8cpp-source.html Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,433 @@ + + +TB10.1 Example Applications: examples/Base/IPC/AdvancedClientServerExample/driver/driver1_ldd.cpp Source File + + + + +

examples/Base/IPC/AdvancedClientServerExample/driver/driver1_ldd.cpp

Go to the documentation of this file.
00001 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+00002 // All rights reserved.
+00003 // This component and the accompanying materials are made available
+00004 // under the terms of "Eclipse Public License v1.0"
+00005 // which accompanies this distribution, and is available
+00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
+00007 //
+00008 // Initial Contributors:
+00009 // Nokia Corporation - initial contribution.
+00010 //
+00011 // Contributors:
+00012 //
+00013 // Description:
+00014 // Example Logical Device Driver
+00015 //
+00016 
+00017 
+00018 
+00023 #include <kern_priv.h>
+00024 #include "driver1.h"
+00025 #include "driver1_dev.h"
+00026 
+00027 _LIT(KDriver1PanicCategory,"Driver1");
+00028 
+00029 //
+00030 // DDriver1Factory
+00031 //
+00032 
+00037 DECLARE_STANDARD_LDD()
+00038         {
+00039         return new DDriver1Factory;
+00040         }
+00041 
+00045 DDriver1Factory::DDriver1Factory()
+00046         {
+00047         // Sets the version number for this device.
+00048         iVersion=RDriver1::VersionRequired();
+00049         // Indicate that we work with a PDD
+00050         iParseMask=KDeviceAllowPhysicalDevice;
+00051         }
+00052 
+00059 TInt DDriver1Factory::Install()
+00060         {
+00061         return SetName(&RDriver1::Name());
+00062         }
+00063 
+00067 DDriver1Factory::~DDriver1Factory()
+00068         {
+00069         }
+00070 
+00076 void DDriver1Factory::GetCaps(TDes8& aDes) const
+00077         {
+00078         // Create a capabilities object
+00079         RDriver1::TCaps caps;
+00080         caps.iVersion = iVersion;
+00081         // Write it back to user memory
+00082         Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps));
+00083         }
+00084 
+00093 TInt DDriver1Factory::Create(DLogicalChannelBase*& aChannel)
+00094         {
+00095         aChannel=new DDriver1Channel;
+00096         if(!aChannel)
+00097                 return KErrNoMemory;
+00098 
+00099         return KErrNone;
+00100         }
+00101 
+00105 DDriver1Channel::DDriver1Channel()
+00106         :       iSendDataDfc(SendDataDfc, this, 1),        // DFC is priority '1'
+00107                 iReceiveDataDfc(ReceiveDataDfc, this, 1)   // DFC is priority '1'
+00108         {
+00109         // Get pointer to client thread's DThread object
+00110         iClient=&Kern::CurrentThread();
+00111 
+00112         // Open a reference on client thread so its control block can't disappear until
+00113         // this driver has finished with it.
+00114         // Note, this call to Open can't fail since it's the thread we are currently running in.
+00115         iClient->Open();
+00116         }
+00117 
+00128 TInt DDriver1Channel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
+00129         {
+00130         // Check Platform Security capabilities of client thread (if required).
+00131         //
+00132         // Here we handle the simple case where:
+00133         // 1. The device driver can only have one client thread
+00134         // 2. The security policy is the binary all-or-nothing policy.
+00135         //    E.g. "If you have the right capability you can do anything with the driver
+00136         //    and if you don't have the capability you can't do anything"
+00137         // 
+00138         // If only some functionality of the driver is restricted, then the security check should
+00139         // go elsewhere, e.g. in DoRequest/DoControl. In that case Kern::CurrentThreadHasCapability()
+00140         // shouldn't be used because the 'current thread' isn't the client.
+00141         //
+00142         // In this example we do a check here for ECapabilityMultimediaDD...
+00143         if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by DRIVER1")))
+00144                 return KErrPermissionDenied;
+00145 
+00146         // Check version
+00147         if (!Kern::QueryVersionSupported(RDriver1::VersionRequired(),aVer))
+00148                 return KErrNotSupported;
+00149 
+00150         // Setup LDD for receiving client messages
+00151         SetDfcQ(Kern::DfcQue0());
+00152         iMsgQ.Receive();
+00153 
+00154         // To receive client messages, associate the DFCs with the queue created above.
+00155         iSendDataDfc.SetDfcQ(iDfcQ);
+00156         iReceiveDataDfc.SetDfcQ(iDfcQ);
+00157 
+00158         // Give PDD a pointer to this channel
+00159         Pdd()->iLdd=this;
+00160 
+00161         // Done
+00162         return KErrNone;
+00163         }
+00164 
+00168 DDriver1Channel::~DDriver1Channel()
+00169         {
+00170         // Cancel all processing that we may be doing
+00171         DoCancel(RDriver1::EAllRequests);
+00172         // Close our reference on the client thread
+00173         Kern::SafeClose((DObject*&)iClient,NULL);
+00174         }
+00175 
+00183 TInt DDriver1Channel::RequestUserHandle(DThread* aThread, TOwnerType aType)
+00184         {
+00185         // Make sure that only our client can get a handle
+00186         if (aType!=EOwnerThread || aThread!=iClient)
+00187                 return KErrAccessDenied;
+00188         return KErrNone;
+00189         }
+00190 
+00202 void DDriver1Channel::HandleMsg(TMessageBase* aMsg)
+00203         {
+00204         TThreadMessage& m=*(TThreadMessage*)aMsg;
+00205 
+00206         // Get message type
+00207         TInt id=m.iValue;
+00208 
+00209         // Decode the message type and dispatch it to the relevent handler function...
+00210         if (id==(TInt)ECloseMsg)
+00211                 {
+00212                 // Channel Close
+00213                 DoCancel(RDriver1::EAllRequests);
+00214                 m.Complete(KErrNone, EFalse);
+00215                 return;
+00216                 }
+00217 
+00218         if (id==KMaxTInt)
+00219                 {
+00220                 // DoCancel
+00221                 DoCancel(m.Int0());
+00222                 m.Complete(KErrNone,ETrue);
+00223                 return;
+00224                 }
+00225 
+00226         if (id<0)
+00227                 {
+00228                 // DoRequest
+00229                 TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
+00230                 TInt r=DoRequest(~id,pS,m.Ptr1(),m.Ptr2());
+00231                 if (r!=KErrNone)
+00232                         Kern::RequestComplete(iClient,pS,r);
+00233                 m.Complete(KErrNone,ETrue);
+00234                 }
+00235         else
+00236                 {
+00237                 // DoControl
+00238                 TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
+00239                 m.Complete(r,ETrue);
+00240                 }
+00241         }
+00242 
+00250 TInt DDriver1Channel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
+00251         {
+00252         (void)a2;   // a2 not used in this example
+00253 
+00254         TInt r;
+00255 
+00256         switch (aFunction)
+00257                 {
+00258                 case RDriver1::EGetConfig:
+00259                         r = GetConfig((TDes8*)a1);
+00260                         break;
+00261 
+00262                 case RDriver1::ESetConfig:
+00263                         r = SetConfig((const TDesC8*)a1);
+00264                         break;
+00265 
+00266                 default:
+00267                         r = KErrNotSupported;
+00268                         break;
+00269                 }
+00270 
+00271         return r;
+00272         }
+00273 
+00282 TInt DDriver1Channel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
+00283         {
+00284         (void)a2;   // a2 not used in this example
+00285 
+00286         TInt r;
+00287 
+00288         switch(aReqNo)
+00289                 {
+00290                 case RDriver1::ESendData:
+00291                         r=SendData(aStatus,(const TDesC8*)a1);
+00292                         break;
+00293 
+00294                 case RDriver1::EReceiveData:
+00295                         r=ReceiveData(aStatus,(TDes8*)a1);
+00296                         break;
+00297 
+00298                 default:
+00299                         r = KErrNotSupported;
+00300                         break;
+00301                 }
+00302 
+00303         return r;
+00304         }
+00305 
+00310 void DDriver1Channel::DoCancel(TUint aMask)
+00311         {
+00312         if(aMask&(1<<RDriver1::ESendData))
+00313                 SendDataCancel();
+00314         if(aMask&(1<<RDriver1::EReceiveData))
+00315                 ReceiveDataCancel();
+00316         }
+00317 
+00318 //
+00319 // Methods for processing configuration control messages
+00320 //
+00321 
+00326 TInt DDriver1Channel::GetConfig(TDes8* aConfigBuf)
+00327         {
+00328         // Create a structure giving the current configuration
+00329         RDriver1::TConfig config;
+00330         CurrentConfig(config);
+00331 
+00332         // Write the config to the client
+00333         TPtrC8 ptr((const TUint8*)&config,sizeof(config));
+00334         return Kern::ThreadDesWrite(iClient,aConfigBuf,ptr,0,KTruncateToMaxLength,NULL);
+00335         }
+00336 
+00341 TInt DDriver1Channel::SetConfig(const TDesC8* aConfigBuf)
+00342         {
+00343         // Don't allow configuration changes whilst we're busy
+00344         if(iSendDataStatus || iReceiveDataStatus)
+00345                 return KErrInUse;
+00346 
+00347         // Create a config structure.
+00348         RDriver1::TConfig config;
+00349         CurrentConfig(config);
+00350 
+00351         // Note: We have filled config with the current settings, this is to allow
+00352         // backwards compatibility when a client gives us an old (and shorter) version
+00353         // of the config structure.
+00354 
+00355         // Read the config structure from client
+00356         TPtr8 ptr((TUint8*)&config,sizeof(config));
+00357         TInt r=Kern::ThreadDesRead(iClient,aConfigBuf,ptr,0);
+00358         if(r!=KErrNone)
+00359                 return r;
+00360 
+00361         // Use config data to setup the driver. Checking that parameters which aren't settable
+00362         // either contain the correct values or are zero (meaning 'default')
+00363         if(config.iPddBufferSize && config.iPddBufferSize!=Pdd()->BufferSize())
+00364                 return KErrArgument;
+00365 
+00366         if(config.iMaxSendDataSize && config.iMaxSendDataSize!=iSendDataBuffer.MaxSize())
+00367                 return KErrArgument;
+00368 
+00369         if(config.iMaxReceiveDataSize && config.iMaxReceiveDataSize!=iReceiveDataBuffer.MaxSize())
+00370                 return KErrArgument;
+00371 
+00372         r=Pdd()->SetSpeed(config.iSpeed);
+00373         if(r!=KErrNone)
+00374                 return r;
+00375 
+00376         return r;
+00377         }
+00378 
+00383 void DDriver1Channel::CurrentConfig(RDriver1::TConfig& aConfig)
+00384         {
+00385         aConfig.iSpeed = Pdd()->Speed();
+00386         aConfig.iPddBufferSize = Pdd()->BufferSize();
+00387         aConfig.iMaxSendDataSize = iSendDataBuffer.MaxSize();
+00388         aConfig.iMaxReceiveDataSize = iReceiveDataBuffer.MaxSize();
+00389         }
+00390 
+00391 //
+00392 // Methods for processing 'SendData'
+00393 //
+00394 
+00402 TInt DDriver1Channel::SendData(TRequestStatus* aStatus,const TDesC8* aData)
+00403         {
+00404         // Check that a 'SendData' isn't already in progress
+00405         if(iSendDataStatus)
+00406                 {
+00407                 Kern::ThreadKill(iClient,EExitPanic,ERequestAlreadyPending,KDriver1PanicCategory);
+00408                 return KErrInUse;
+00409                 }
+00410 
+00411         // Read data from client into our buffer
+00412         TInt r=Kern::ThreadDesRead(iClient,aData,iSendDataBuffer,0);
+00413         if(r!=KErrNone)
+00414                 return r;
+00415 
+00416         // Give data to PDD so that it can do the work
+00417         r=Pdd()->SendData(iSendDataBuffer);
+00418         if(r!=KErrNone)
+00419                 return r;
+00420 
+00421         // Save the client request status and return
+00422         iSendDataStatus = aStatus;
+00423         return KErrNone;
+00424         }
+00425 
+00429 void DDriver1Channel::SendDataCancel()
+00430         {
+00431         if(iSendDataStatus)
+00432                 {
+00433                 // Tell PDD to stop processing the request
+00434                 Pdd()->SendDataCancel();
+00435                 // Cancel DFC
+00436                 iSendDataDfc.Cancel();
+00437                 // Complete client's request
+00438                 Kern::RequestComplete(iClient,iSendDataStatus,KErrCancel);
+00439                 }
+00440         }
+00441 
+00445 void DDriver1Channel::SendDataComplete(TInt aResult)
+00446         {
+00447         // Save result code
+00448         iSendDataResult = aResult;
+00449         // Queue DFC
+00450         iSendDataDfc.Add();
+00451         }
+00452 
+00457 void DDriver1Channel::SendDataDfc(TAny* aPtr)
+00458         {
+00459         ((DDriver1Channel*)aPtr)->DoSendDataComplete();
+00460         }
+00461 
+00465 void DDriver1Channel::DoSendDataComplete()
+00466         {
+00467         TInt result = iSendDataResult;
+00468         // Complete clients request
+00469         Kern::RequestComplete(iClient,iSendDataStatus,result);
+00470         }
+00471 
+00472 //
+00473 // Methods for processing 'ReceiveData'
+00474 //
+00475 
+00482 TInt DDriver1Channel::ReceiveData(TRequestStatus* aStatus,TDes8* aPtr)
+00483         {
+00484         // Check that a 'ReceiveData' isn't already in progress
+00485         if(iReceiveDataStatus)
+00486                 {
+00487                 Kern::ThreadKill(iClient,EExitPanic,ERequestAlreadyPending,KDriver1PanicCategory);
+00488                 return KErrInUse;
+00489                 }
+00490 
+00491         // Ask PDD for data
+00492         TInt r=Pdd()->ReceiveData(iReceiveDataBuffer);
+00493         if(r!=KErrNone)
+00494                 return r;
+00495 
+00496         // Save the client request status and descriptor before returning
+00497         iReceiveDataStatus = aStatus;
+00498         iReceiveDataDescriptor = aPtr;
+00499         return KErrNone;
+00500         }
+00501 
+00505 void DDriver1Channel::ReceiveDataCancel()
+00506         {
+00507         if(iReceiveDataStatus)
+00508                 {
+00509                 // Tell PDD to stop processing the request
+00510                 Pdd()->ReceiveDataCancel();
+00511                 // Cancel DFC
+00512                 iReceiveDataDfc.Cancel();
+00513                 // Finished with client descriptor, so NULL it to help detect coding errors
+00514                 iReceiveDataDescriptor = NULL;
+00515                 // Complete clients request
+00516                 Kern::RequestComplete(iClient,iReceiveDataStatus,KErrCancel);
+00517                 }
+00518         }
+00519 
+00523 void DDriver1Channel::ReceiveDataComplete(TInt aResult)
+00524         {
+00525         // Save result code
+00526         iReceiveDataResult = aResult;
+00527         // Queue DFC
+00528         iReceiveDataDfc.Add();
+00529         }
+00530 
+00535 void DDriver1Channel::ReceiveDataDfc(TAny* aPtr)
+00536         {
+00537         ((DDriver1Channel*)aPtr)->DoReceiveDataComplete();
+00538         }
+00539 
+00543 void DDriver1Channel::DoReceiveDataComplete()
+00544         {
+00545         // Write data to client from our buffer
+00546         TInt result=Kern::ThreadDesWrite(iClient,iReceiveDataDescriptor,iReceiveDataBuffer,0);
+00547 
+00548         // Finished with client descriptor, so NULL it to help detect coding errors
+00549         iReceiveDataDescriptor = NULL;
+00550 
+00551         // Use result code from PDD if it was an error
+00552         if(iReceiveDataResult!=KErrNone)
+00553                 result = iReceiveDataResult;
+00554 
+00555         // Complete client's request
+00556         Kern::RequestComplete(iClient,iReceiveDataStatus,result);
+00557         }
+00558 
+

Generated on Thu Jan 21 10:32:56 2010 for TB10.1 Example Applications by  + +doxygen 1.5.3
+ +