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

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010   this list of conditions and the following disclaimer in the documentation
00011   and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013   may be used to endorse or promote products derived from this software
00014   without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description: Example Physical Device Driver. 
00028 */
00029 
00030 
00031 
00036 #include <kern_priv.h>
00037 #include "driver1.h"
00038 #include "driver1_dev.h"
00039 
00043 class DDevice1PddFactory : public DPhysicalDevice
00044         {
00045 public:
00046         DDevice1PddFactory();
00047         
00048         // Inherited from DPhysicalDevice
00049         virtual TInt Install();
00050         virtual void GetCaps(TDes8& aDes) const;
00051         virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
00052         virtual TInt Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
00053 public:
00054         TInt iHardwareInUse;
00055 private:
00059         enum TMinimumLDDVersion
00060                 {
00061                 EMinimumLddMajorVersion=1,
00062                 EMinimumLddMinorVersion=0,
00063                 EMinimumLddBuild=0 //Not used
00064                 };
00065         };
00066 
00067 // Name for PDD, must match LDD name with a '.' and distinguishing name appended
00068 _LIT(KDriver1PddName,"DRIVER1.template");
00069 
00073 class DDriver1Device : public DDriver1
00074         {
00075 public:
00076         DDriver1Device(DDevice1PddFactory* aFactory);
00077         ~DDriver1Device();
00078         TInt DoCreate();
00079         
00080         // Inherited from DDriver1. These functions are called by the LDD.
00081         virtual TInt BufferSize() const;
00082         virtual TInt Speed() const;
00083         virtual TInt SetSpeed(TInt aSpeed);
00084         virtual TInt SendData(const TDesC8& aData);
00085         virtual void SendDataCancel();
00086         virtual TInt ReceiveData(TDes8& aBuffer);
00087         virtual void ReceiveDataCancel();
00088 private:
00089         static void SendDataTimerCallback(TAny* aPtr);
00090         void SendDataCallback();
00091         static void ReceiveDataTimerCallback(TAny* aPtr);
00092         void ReceiveDataCallback();
00093 private:
00094         DDevice1PddFactory* iFactory;
00095         TInt iSpeed;
00096         NTimer iSendDataTimer;
00097         NTimer iReceiveDataTimer;
00098         TBuf8<256> iBuffer;
00099         TDes8* iReceiveBuffer;
00100         };
00101 //
00102 // DDevice1PddFactory
00103 //
00104 
00109 DECLARE_STANDARD_PDD()
00110         {
00111         return new DDevice1PddFactory;
00112         }
00113 
00114 DDevice1PddFactory::DDevice1PddFactory()
00115         {
00116         // Sets version number for this device
00117         iVersion=RDriver1::VersionRequired();
00118         }
00119 
00125 TInt DDevice1PddFactory::Install()
00126         {
00127         return SetName(&KDriver1PddName);
00128         }
00129 
00135 void DDevice1PddFactory::GetCaps(TDes8& aDes) const
00136         {
00137         // Create a capabilities object
00138         DDriver1::TCaps caps;
00139         caps.iVersion = iVersion;
00140         // Zero the buffer
00141         TInt maxLen = aDes.MaxLength();
00142         aDes.FillZ(maxLen);
00143         // Copy capabilities
00144         TInt size=sizeof(caps);
00145         if(size>maxLen)
00146                 size=maxLen;
00147         aDes.Copy((TUint8*)&caps,size);
00148         }
00149 
00161 TInt DDevice1PddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
00162         {
00163         // Ignore the parameters we aren't interested in...
00164         (void)aUnit;
00165         (void)aInfo;
00166         (void)aVer;
00167 
00168         // Create a new physical channel
00169         DDriver1Device* device=new DDriver1Device(this);
00170         aChannel=device;
00171         if (!device)
00172                 return KErrNoMemory;
00173         return device->DoCreate();
00174         }
00175 
00186 TInt DDevice1PddFactory::Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
00187         {
00188         // Check version numbers
00189         if ((!Kern::QueryVersionSupported(iVersion,aVer)) || (!Kern::QueryVersionSupported(aVer,TVersion(EMinimumLddMajorVersion,EMinimumLddMinorVersion,EMinimumLddBuild))))
00190                 return KErrNotSupported;
00191 
00192         // We don't support units
00193     if (aUnit != -1)
00194         return KErrNotSupported;
00195 
00196         // Ignore extra info, (this could be used for validation purposes).
00197         // Note, aInfo is a pointer to a descriptor in user memory, therefore safe methods should
00198         // be used for reading its contents e.g. using Kern::KUDesGet()
00199         (void)aInfo;
00200 
00201         // OK
00202         return KErrNone;
00203         }
00204 
00208 DDriver1Device::DDriver1Device(DDevice1PddFactory* aFactory)
00209         :       iFactory(aFactory),
00210                 iSpeed(100000),  // 100000us (100ms) per byte
00211                 iSendDataTimer(SendDataTimerCallback,this),
00212                 iReceiveDataTimer(ReceiveDataTimerCallback,this)
00213         {
00214         }
00215 
00219 DDriver1Device::~DDriver1Device()
00220         {
00221         // Driver no longer using hardware resources
00222         NKern::LockedDec(iFactory->iHardwareInUse);
00223         }
00224 
00225 TInt DDriver1Device::DoCreate()
00226         {
00227         // Claim the hardware resources by incrementing iHardwareInUse.
00228         // Must do this before any other failure can happen in this function so that
00229         // the destructor can safely decrement iHardwareInUse.
00230         //
00231         // This method of ensuring hardware is only in use by one driver at a time
00232         // wouldn't be needed if the driver claimed real hardware resources which
00233         // could only be used once. E.g. binding to an interrupt.
00234         if(NKern::LockedInc(iFactory->iHardwareInUse))
00235                 return KErrInUse;
00236 
00237         // Other setup goes here
00238         return KErrNone;
00239         }
00243 TInt DDriver1Device::BufferSize() const
00244         {
00245         return iBuffer.MaxSize();
00246         }
00247         
00251 TInt DDriver1Device::Speed() const
00252         {
00253         return iSpeed;
00254         }
00255 
00260 TInt DDriver1Device::SetSpeed(TInt aSpeed)
00261         {
00262         if(aSpeed<=0)
00263                 return KErrArgument;
00264         iSpeed = aSpeed;
00265         return KErrNone;
00266         }
00267 
00268 // Methods for processing 'SendData'
00269 //
00273 TInt DDriver1Device::SendData(const TDesC8& aData)
00274         {
00275         // Save the last part of the data to 'send', we will pretend to 'receive' this later
00276         iBuffer=aData.Right(iBuffer.MaxSize());
00277         // Pretend to send the data by waiting for iSpeed micro-seconds per byte...
00278         iSendDataTimer.OneShot(aData.Size()*iSpeed/NKern::TickPeriod());
00279         return KErrNone;
00280         }
00281 
00285 void DDriver1Device::SendDataCancel()
00286         {
00287         // Stop the timer we were using to pretend we were processing the send.
00288         iSendDataTimer.Cancel();
00289         }
00290 
00295 void DDriver1Device::SendDataTimerCallback(TAny* aPtr)
00296         {
00297         // Just forward callback to non-static callback function
00298         ((DDriver1Device*)aPtr)->SendDataCallback();
00299         }
00300 
00304 void DDriver1Device::SendDataCallback()
00305         {
00306         // Tell LDD we've finished
00307         iLdd->SendDataComplete(KErrNone);
00308         }
00309         
00310 //
00311 // Methods for processing 'ReceiveData'
00312 //
00316 TInt DDriver1Device::ReceiveData(TDes8& aBuffer)
00317         {
00318         // Save a pointer to the buffer we need to put the 'received' data in
00319         iReceiveBuffer=&aBuffer;
00320         // Pretend to receive the data by waiting for iSpeed micro-seconds per byte...
00321         iReceiveDataTimer.OneShot(iBuffer.Size()*iSpeed/NKern::TickPeriod());
00322         return KErrNone;
00323         }
00327 void DDriver1Device::ReceiveDataCancel()
00328         {
00329         // Stop the timer we were using to pretend we were processing the receive
00330         iReceiveDataTimer.Cancel();
00331         }
00336 void DDriver1Device::ReceiveDataTimerCallback(TAny* aPtr)
00337         {
00338         // Just forward callback to non-static callback function
00339         ((DDriver1Device*)aPtr)->ReceiveDataCallback();
00340         }
00344 void DDriver1Device::ReceiveDataCallback()
00345         {
00346         // Pretend the data we have received is that saved in iBuffer when we last did a send
00347         *iReceiveBuffer=iBuffer;
00348         // Tell LDD we've finished
00349         iLdd->ReceiveDataComplete(KErrNone);
00350         }

Generated by  doxygen 1.6.2