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 }
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.