examples/Base/IPC/AdvancedClientServerExample/ProcessServer/src/processserver.cpp

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:  
00028 */
00029 
00030 
00031 #include "processserver.h"
00032 #include "processserverstart.h"
00033 #include "processserversession.h"
00034 #include<e32debug.h>
00035 
00036 const TInt KProcessServerShutDownDelay = 50000000; //50 sec
00037 
00038 //******CProcessServer******//
00039 void CProcessServer::NewLC()
00040         {
00041         CProcessServer* s = new(ELeave) CProcessServer();
00042         CleanupStack::PushL(s);
00043         s->ConstructL();
00044         }
00048 CProcessServer::CProcessServer()
00049         :CServer2(EPriorityStandard, ESharableSessions),iDriverState(EStateUnknown)
00050         {
00051         }
00055 void CProcessServer::ConstructL()
00056         {
00057         // Call CServer2::StartL() before any other functions inside ConstructL()
00058         // to avoid an error other than KErrAlreadyExists when the duplicate server starts
00059         StartL(KProcessServerName);
00060         iDelayProcessServerShutDown = CDelayServerShutDown::NewL();
00061         }
00065 CProcessServer::~CProcessServer()
00066         {
00067         if (iDelayProcessServerShutDown)
00068                 {
00069                 iDelayProcessServerShutDown->Cancel();
00070                 delete iDelayProcessServerShutDown;
00071                 }
00072                 
00073         // unload device driver when server terminated
00074         UnloadDevice();
00075         }
00082 CSession2* CProcessServer::NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const
00083         {
00084         //check whether version is compatible
00085         TVersion v(KProcessServerVersion,KProcessServerMinorVersionNumber,KProcessServerBuildVersionNumber);
00086         if(!User::QueryVersionSupported(v, aVersion))
00087                 User::Leave(KErrNotSupported);
00088         
00089         // check client process has the required capability
00090         if(!aMessage.HasCapability(ECapabilityMultimediaDD))
00091                 User::Leave(KErrPermissionDenied);              
00092 
00093         // construct and return the server side client session object
00094         CProcessServer& ncThis = const_cast<CProcessServer&>(*this);
00095         CProcessServerSession* serverSession = CProcessServerSession::NewL(ncThis);
00096         return serverSession;
00097         }
00101 void CProcessServer::IncrementRefCount()
00102         {
00103         iRefCount++;
00104         iDelayProcessServerShutDown->Cancel(); // Cancel shutdown if it has started due to no clients being connected 
00105         }
00106         
00110 void CProcessServer::DecrementRefCount() 
00111         {
00112         iRefCount--;
00113         if ( iRefCount == 0 )
00114                 {
00115                 iDelayProcessServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(KProcessServerShutDownDelay));
00116                 }
00117         }
00122 TInt CProcessServer::LoadDevice()
00123         {
00124         if (iDriverState>=EDriverLoaded && iDriverState<EDriverUnloaded)
00125                 return KErrNone; //Device has been loaded, return immediately
00126                 
00127         TInt r=User::LoadPhysicalDevice(KDriver1PddFileName);
00128         if (r!=KErrNone && r!=KErrAlreadyExists)
00129                 {
00130                 return r; //some error occurred
00131                 }
00132 
00133         r = User::LoadLogicalDevice(KDriver1LddFileName);
00134         if (r!=KErrNone && r!=KErrAlreadyExists)
00135                 {
00136                 return r; //some error occurred 
00137                 }
00138 
00139         //both PDD and LDD have been loaded
00140         UpdateDriverState(EDriverLoaded);
00141         return KErrNone; 
00142         }
00147 TInt CProcessServer::UnloadDevice()
00148         {
00149         if (iDriverState==EDriverUnloaded || iDriverState == EStateUnknown)
00150                 return KErrNone; //no device is loaded, return immediately
00151                 
00152         // close device
00153         if (iDriver.Handle())
00154                 iDriver.Close();
00155         // Unload Logical Device
00156         TInt r = User::FreeLogicalDevice(RDriver1::Name());
00157         if (r!=KErrNone)
00158                 return r;
00159         // Unload Physical Device
00160         TName pddName(RDriver1::Name());
00161         _LIT(KVariantExtension,".template");
00162         pddName.Append(KVariantExtension);
00163         r=User::FreePhysicalDevice(pddName);
00164         
00165         if (KErrNone==r)
00166                 UpdateDriverState(EDriverUnloaded);     
00167         return r;
00168         }
00173 TInt CProcessServer::OpenLogicalChannel()
00174         {
00175         if (iDriverState>=ELogicalChannelOpened && iDriverState<ELogicalChannelClosed)
00176                 return KErrNone;
00177         
00178         TInt r = iDriver.Open();
00179         if (KErrNone==r)
00180                 UpdateDriverState(ELogicalChannelOpened);
00181         
00182         return r;
00183         }
00187 void CProcessServer::CloseLogicalChannel()
00188         {
00189         if (iDriver.Handle())
00190                 {
00191                 iDriver.Close();
00192                 UpdateDriverState(ELogicalChannelClosed);
00193                 }
00194         }
00201 TInt CProcessServer::SendDataToDevice(TRequestStatus& aStatus, const TDesC8& aData)
00202         {
00203         TInt r = KErrNone;
00204         if (iDriverState>=ELogicalChannelOpened && iDriverState<ELogicalChannelClosed)
00205                 {
00206                 iDriver.SendData(aStatus, aData);
00207                 UpdateDriverState(ESendingData);
00208                 }
00209         else
00210                 {
00211                 r = KErrArgument;
00212                 }
00213         return r;
00214         }
00218 void CProcessServer::CancelSendData()
00219         {
00220         iDriver.SendDataCancel();
00221         UpdateDriverState(ELogicalChannelOpened);
00222         }
00227 void CProcessServer::UpdateDriverState(TDriverState aState)
00228         {
00229         iDriverState = aState;
00230         }
00231 
00232 //EOF

Generated by  doxygen 1.6.2