examples/Base/IPC/ClientServer/Simple/SimpleServer.cpp

00001 // Copyright (c) 2000-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 // The implementation of our simple server that increments and decrements a simple counter value.
00015 // **NOTE**: The example does not demonstrate any security features - its purpose is simply
00016 // to demonstrate the basic principles of client/server interaction.
00017 //
00018 
00019 
00020 #include "ClientServer.h"
00021 #include "SimpleServer.h"
00022 #include <e32svr.h>
00023 #include <e32uid.h>
00024 
00025 
00026 //**********************************
00027 //CCountServServer - implementations
00028 //**********************************
00029 
00040 CCountServServer::CCountServServer(CActive::TPriority aActiveObjectPriority)
00041         : CServer2(aActiveObjectPriority)
00042         {
00043         }
00044 
00045 
00049 CSession2* CCountServServer::NewSessionL(const TVersion& aVersion,const RMessage2& /*aMessage*/) const
00050     {
00051       // Check that the version is OK
00052     TVersion v(KCountServMajorVersionNumber,KCountServMinorVersionNumber,KCountServBuildVersionNumber);
00053         if (!User::QueryVersionSupported(v,aVersion))
00054                 User::Leave(KErrNotSupported);  
00055         
00056         // CAN USE THE aMessage argument to check client's security and identity
00057         // can make use of this later but for now ignore. AH 4/5/05
00058         // the connect message is delivered via the RMessage2 object passed. 
00059         
00060         // do something with this later (and move it to the start of the function?)
00061         
00062           // Create the session.
00063         return new (ELeave) CCountServSession;
00064         }
00065 
00066 
00070 void CCountServServer::PanicServer(TCountServPanic aPanic)
00071         {
00072         _LIT(KTxtServerPanic,"Count server panic");
00073         User::Panic(KTxtServerPanic,aPanic);
00074         }
00075 
00076 
00077 //***********************************
00078 //CCountServSession - implementations
00079 //***********************************
00080 
00081 
00085 CCountServSession::CCountServSession()
00086         {
00087     }
00088 
00092 void CCountServSession::ServiceL(const RMessage2& aMessage)
00093         {
00094         TRAPD(err,DispatchMessageL(aMessage));
00095         aMessage.Complete(err);
00096         }
00097 
00104 void CCountServSession::DispatchMessageL(const RMessage2& aMessage)
00105         {
00106         switch (aMessage.Function())
00107         {
00108         case ECountServSetFromString:
00109                 SetFromStringL(aMessage);
00110                 return;
00111         case ECountServIncrease:
00112                 Increase();
00113                 return;
00114         case ECountServIncreaseBy:
00115                 IncreaseBy(aMessage);
00116                 return;
00117         case ECountServDecrease:
00118                 Decrease();
00119                 return;
00120         case ECountServDecreaseBy:
00121                 DecreaseBy(aMessage);
00122                 return;
00123         case ECountServReset:
00124                 Reset();
00125                 return;
00126         case ECountServValue:
00127                 CounterValueL(aMessage);
00128                 return;
00129           
00130           // This is an example of a request that we know about, but don't support.
00131           // We cause KErrNotSupported to be returned to the client.
00132         case ECountServUnsupportedRequest:
00133                 User::Leave(KErrNotSupported);
00134                 
00135          //  Requests that we don't understand at all are a different matter.
00136          //  This is considered a client programming error, so we panic the 
00137          //  client - this also completes the message.
00138         default:
00139                 PanicClient(aMessage,EBadRequest);
00140                 return;
00141         }
00142         }
00143 
00149 void CCountServSession::SetFromStringL(const RMessage2& aMessage)
00150         {
00151         
00152           // length of passed descriptor (1st parameter passed from client)
00153         TInt deslen = aMessage.GetDesLength(0);
00154         
00155           // Passed data will be saved in this descriptor.
00156     RBuf buffer;
00157       
00158       // Max length set to the value of "deslen", but current length is zero
00159     buffer.CreateL(deslen);
00160       
00161       // Do the right cleanup if anything subsequently goes wrong
00162     buffer.CleanupClosePushL();
00163     
00164       // Copy the client's descriptor data into our buffer.
00165     aMessage.ReadL(0,buffer,0);
00166     
00167       // Now do a validation to make sure that the string only has digits
00168     if (buffer.Length() == 0)
00169         {
00170         User::Leave(ENonNumericString);
00171         }
00172     
00173     TLex16 lexer;
00174     
00175     lexer.Assign(buffer);
00176     while (!lexer.Eos())
00177         {
00178         TChar thechar;
00179         
00180         thechar = lexer.Peek();
00181         if (!thechar.IsDigit())
00182             {
00183                 User::Leave(ENonNumericString);
00184             }
00185         lexer.Inc();
00186         }
00187        
00188       // Convert to a simple TInt value. 
00189     lexer.Assign(buffer);           
00190     if (lexer.Val(iCount))
00191         {
00192         User::Leave(ENonNumericString);
00193         }
00194         
00195           // Clean up the memory acquired by the RBuf variable "buffer"
00196         CleanupStack::PopAndDestroy();
00197         }
00198 
00199 
00203 void CCountServSession::Increase()
00204         {
00205         iCount++;
00206         }
00207 
00208 
00212 void CCountServSession::IncreaseBy(const RMessage2& aMessage)
00213         {
00214         iCount = iCount + aMessage.Int0();
00215         }
00216 
00220 void CCountServSession::Decrease()
00221         {
00222         iCount--;
00223         }
00224 
00225 
00229 void CCountServSession::DecreaseBy(const RMessage2& aMessage)
00230         {
00231         iCount = iCount - aMessage.Int0();      
00232         }
00233 
00234 
00238 void CCountServSession::Reset()
00239         {
00240         iCount=0;
00241         }
00242 
00243 
00248 void CCountServSession::CounterValueL(const RMessage2& aMessage)
00249         {
00250         TPckgBuf<TInt> p(iCount);
00251         aMessage.WriteL(0,p);
00252         }
00253 
00254 
00258 void CCountServSession::PanicClient(const RMessage2& aMessage,TInt aPanic) const
00259         {
00260         _LIT(KTxtServer,"CountServ server");
00261         aMessage.Panic(KTxtServer,aPanic);
00262         }
00263 
00264 
00265 
00266 //**********************************
00267 //Global functions
00268 //**********************************
00269 
00270 // The count server thread function that initialises the server.
00271 GLDEF_C TInt CCountServServer::ThreadFunction(TAny* )
00272         {
00273           // get clean-up stack
00274         CTrapCleanup* cleanup=CTrapCleanup::New();
00275         if (cleanup == NULL)
00276             {
00277                 CCountServServer::PanicServer(ECreateTrapCleanup);
00278             }
00279         
00280           // create an active scheduler and server
00281         CActiveScheduler *pA=new CActiveScheduler;
00282         __ASSERT_ALWAYS(pA!=NULL,CCountServServer::PanicServer(EMainSchedulerError));
00283         CCountServServer *pS=new CCountServServer(EPriorityStandard);
00284         __ASSERT_ALWAYS(pS!=NULL,CCountServServer::PanicServer(ESvrCreateServer));
00285                 
00286           //Install the active scheduler
00287         CActiveScheduler::Install(pA);
00288           
00289           // Start the server
00290         TInt err = pS->Start(KCountServerName);
00291         if (err != KErrNone)
00292             {
00293                 CCountServServer::PanicServer(ESvrStartServer);
00294             }
00295         
00296       // Let everyone know that we are ready to
00297       // deal with requests.
00298     RThread::Rendezvous(KErrNone);
00299         
00300           // And start fielding requests from client(s).
00301         CActiveScheduler::Start();
00302 
00303       // Tidy up...     
00304     delete pS;
00305     delete pA;
00306     delete cleanup; 
00307     
00308           // ...although we should never get here!
00309         return(KErrNone);
00310         }
00311 
00312 
00320 EXPORT_C TInt StartThread(RThread& aServerThread)
00321     {
00322         TInt res=KErrNone;
00323         
00324           // Create the server, if one with this name does not already exist.
00325         TFindServer findCountServer(KCountServerName);
00326         TFullName   name;
00327         
00328           // Need to check that the server exists.
00329         if (findCountServer.Next(name)!=KErrNone)
00330                 {
00331                   // Create the thread for the server.
00332                 res=aServerThread.Create(KCountServerName,
00333                         CCountServServer::ThreadFunction,
00334                         KDefaultStackSize,
00335                         KDefaultHeapSize,
00336                         KDefaultHeapSize,
00337                         NULL
00338                         );
00339                         
00340           // The thread has been created OK so get it started - however
00341           // we need to make sure that it has started before we continue.
00342                 if (res==KErrNone)
00343                         {
00344                         TRequestStatus rendezvousStatus;
00345                         
00346                         aServerThread.SetPriority(EPriorityNormal);
00347                         aServerThread.Rendezvous(rendezvousStatus);
00348                         aServerThread.Resume();
00349                         User::WaitForRequest(rendezvousStatus);
00350                         }
00351                         
00352                   // The thread has not been created - clearly there's been a problem.
00353                 else
00354                         {
00355                         aServerThread.Close();
00356                         }
00357                 }
00358     return res;
00359     }

Generated by  doxygen 1.6.2