examples/SFExamples/RockPaperScissorsGameSourceCode_S60/RPS/src/BluetoothResponder.cpp

00001 /*
00002 Copyright (c) 2002-2011 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 // INCLUDE FILES
00031 
00032 #include "BluetoothResponder.h"
00033 #include "BluetoothServiceAdvertiser.h"
00034 #include "BluetoothSocketWriterReader.h"
00035 #include "common.hrh"
00036 
00037 const TInt KQueueSize = 1;
00038 
00039 /*
00040 ============================================================================
00041 CBluetoothResponder's two stage constructor
00042 ============================================================================
00043 */
00044 CBluetoothResponder* CBluetoothResponder::NewL(MBluetoothObserver& aRespObs, RSocketServ& aSocketServer)
00045         {
00046     CBluetoothResponder* self = new (ELeave) CBluetoothResponder(aRespObs, aSocketServer);
00047     CleanupStack::PushL(self);
00048     self->ConstructL();
00049     CleanupStack::Pop();
00050     return self;
00051         }
00052 
00053 /*
00054 ============================================================================
00055 CBluetoothResponder's second phase constructor 
00056 ============================================================================
00057 */
00058 void CBluetoothResponder::ConstructL()
00059         {
00060         iServiceAdvertiser = new(ELeave) CBluetoothServiceAdvertiser(*this);
00061         iBtSocketReader = new(ELeave) CSocketReader(iAcceptingSocket, *this);
00062         iBtSocketWriter = new(ELeave) CSocketWriter(iAcceptingSocket, *this);   
00063         }
00064 
00065 /*
00066 ============================================================================
00067 CBluetoothResponder's constructor 
00068 ============================================================================
00069 */
00070 CBluetoothResponder::CBluetoothResponder(MBluetoothObserver& aRespObs, RSocketServ& aSocketServer):
00071  CBluetoothConnectionBase(EFalse), iRespObs(aRespObs), iSocketServer(aSocketServer), iState(EIdle)
00072         {
00073         TUid settingsUID;
00074         settingsUID.iUid = KRPS_BTServiceID;
00075         iBtSecurity.SetUid(settingsUID);
00076         iBtSecurity.SetAuthentication(EFalse);
00077         iBtSecurity.SetAuthorisation(EFalse);
00078         iBtSecurity.SetEncryption(EFalse);
00079         }
00080 
00081 /*
00082 ============================================================================
00083 CBluetoothResponder's destructor
00084 ============================================================================
00085 */
00086 CBluetoothResponder::~CBluetoothResponder()
00087         {
00088         Cancel();
00089         delete iServiceAdvertiser;
00090         delete iBtSocketReader;
00091         delete iBtSocketWriter;
00092         iAcceptingSocket.Close();       
00093         iListeningSocket.Close();
00094         }
00095 
00096 /*
00097 ============================================================================
00098 DoCancel is called as part of the active object's Cancel().
00099 Cancels all outstanding BT socket operations
00100 ============================================================================
00101 */
00102 void CBluetoothResponder::DoCancel()
00103         {
00104         iListeningSocket.CancelAll();
00105         iAcceptingSocket.CancelAll();
00106         if(iBtSocketReader->IsActive())
00107                 {               
00108                 iBtSocketReader->Cancel();
00109                 }
00110         if(iBtSocketWriter->IsActive())
00111                 {               
00112                 iBtSocketWriter->Cancel();
00113                 }
00114         }
00115 
00116 /*
00117 ============================================================================
00118 Entry point of the CBluetoothResponder's state machine. The initial state must be EIdle.
00119 A state other than EIdle will result in a KErrInUse. This is to prevent StartL() calling
00120 more than once if the state machine is already active.
00121 ============================================================================
00122 */
00123 void CBluetoothResponder::StartL()
00124         {
00125         if (iState != EIdle)
00126                 {
00127                 User::Leave(KErrInUse);
00128                 }
00129                 
00130         TRAPD(err,FindAvailablePortL());
00131         if(err!=KErrNone)
00132                 {
00133                 iListeningSocket.Close();
00134                 User::Leave(err);       
00135                 }
00136         }
00137 
00138 /*
00139 ============================================================================
00140 Handles CBluetoothResponder's state machine completion events 
00141 ============================================================================
00142 */
00143 void CBluetoothResponder::RunL()
00144         {
00145         User::LeaveIfError(iStatus.Int());//The error is handled in the RunError
00146         
00147     switch (iState)
00148         {
00149         case EIdle:
00150                 //State machine entry point
00151                 break;
00152         case EFindingAvailablePort:
00153                 //Founding available port completed, start binding the listening socket to the port
00154                 BindToPortL();
00155             break;   
00156         case EBinding:
00157                 //Binding completed, start advertising the service
00158                 iServiceAdvertiser->StartL(iPort);
00159                 iState = EAdvertising;
00160             break;   
00161         case EAdvertising:
00162                 //Advertising completed, start setting BT security
00163                 RegisterService();
00164             break;   
00165         case ERegisteringService:
00166                 //Setting BT security completed, start listening for incoming connection 
00167                 ListenL();
00168             break;   
00169         case EListening:
00170                 //Remote device connected, start listening for incoming data
00171                 iRespObs.ConnectionErr(iHandle, KErrNone);
00172         case EWaitingForData:
00173                 //Incoming data received, start listening for incoming data
00174         case ESendingData:
00175                 //Sending data completed, start listening for incoming data
00176                 WaitForData();
00177             break;
00178         default:
00179             User::Leave(KErrCorrupt);
00180             break;
00181         };      
00182         }
00183 
00184 
00185 /*
00186 ============================================================================
00187 Opens a socket using the RFCOMM protocol and ask for an available RFCOMM port.
00188 ============================================================================
00189 */
00190 void CBluetoothResponder::FindAvailablePortL()
00191         {
00192         iState = EFindingAvailablePort;
00193         User::LeaveIfError(iListeningSocket.Open(iSocketServer, KBTRFCOMM));
00194         /*
00195         ============================================================================
00196         Get RFCOMM available port if any. Note that you can also try to get any available port manually.
00197         You can try to bind the listening socket to the current value of iPort (KPort).
00198         If this fails, increment the port until you exhaust all the ports (KMaxTUint8) or find an available one.
00199         ============================================================================
00200         */
00201         User::LeaveIfError(iListeningSocket.GetOpt(KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, iPort));
00202         SelfComplete();
00203         }
00204 
00205 /*
00206 ============================================================================
00207 Attempts to bind the listening socket to the BT device address and to an available RFCOMM port and start listening for
00208 incoming remote device connection (Master connection)
00209 ============================================================================
00210 */
00211 void CBluetoothResponder::BindToPortL()
00212         {
00213         iState = EBinding;
00214         iBtSocketAddr.SetPort(iPort);
00215         User::LeaveIfError(iListeningSocket.Bind(iBtSocketAddr));
00216         User::LeaveIfError(iListeningSocket.Listen(KQueueSize));        
00217         SelfComplete();
00218         }
00219 
00220 /*
00221 ============================================================================
00222 Attaches the BT security settings to the listening socket
00223 ============================================================================
00224 */
00225 void CBluetoothResponder::RegisterService()
00226         {
00227         iBtSocketAddr.SetSecurity(iBtSecurity);
00228         iState = ERegisteringService;
00229         SelfComplete();
00230         }
00231 
00232 /*
00233 ============================================================================
00234 Sets up the BT socket to listen for incoming connection (Master connection)
00235 ============================================================================
00236 */
00237 void CBluetoothResponder::ListenL()
00238         {
00239         iState = EListening;
00240         /*
00241         ============================================================================
00242         Closes old accepted socket if open
00243         ============================================================================
00244         */
00245         iAcceptingSocket.Close();
00246 
00247         /*
00248         ============================================================================
00249         Opens a blank socket
00250         ============================================================================
00251         */
00252         User::LeaveIfError(iAcceptingSocket.Open(iSocketServer));
00253 
00254         /*
00255         ============================================================================
00256         Waits for incoming connection. The RunL will handle it.
00257         ============================================================================
00258         */
00259         iListeningSocket.Accept(iAcceptingSocket, iStatus);
00260         SetActive();
00261         }
00262 
00263 /*
00264 ============================================================================
00265 Sets the state machine in the listening mode for remote device's incoming data.
00266 Listening is done with CSocketReader (a separate active object). On completion CSocketReader calls the callback
00267 CBluetoothResponder::ReportData either with the data from the remote device or with an error.
00268 ============================================================================
00269 */              
00270 void CBluetoothResponder::WaitForData()
00271         {
00272         if(!iBtSocketReader->IsActive())
00273                 {                       
00274                 iBtSocketReader->ReadData();
00275                 iState=EWaitingForData;
00276                 }
00277         }
00278 
00279 /*
00280 ============================================================================
00281 Sends the data to the remote device (Master). RunL will handle the sending data completion
00282 ============================================================================
00283 */              
00284 void CBluetoothResponder::SendData(const TDesC8& aData)
00285         {
00286         //If CSocketWriter is already active we discard the data to send. RPS doesn't need to queue events.
00287         //You can change CSocketWriter's implementation to support queuing of events if your multiplayer game needs to. 
00288         if(!iBtSocketWriter->IsActive())
00289                 {                       
00290                 iBtSocketWriter->Write(aData);
00291                 iState=ESendingData;
00292                 }
00293         }
00294         
00295 
00296 /*
00297 ============================================================================
00298 Callback from CBluetoothServiceAdvertiser if an error occurs during service advertising. 
00299 ============================================================================
00300 */
00301 void CBluetoothResponder::ReportAdvertiserErr(TInt aError)
00302         {
00303         //Informs the observer of the error
00304         iRespObs.ConnectionErr(iHandle, aError);                        
00305         }
00306 
00307 /*
00308 ============================================================================
00309 Callback from CBluetoothServiceAdvertiser when the advertising of the service is succesfully completed
00310 ============================================================================
00311 */
00312 void CBluetoothResponder::AdvertiserComplete()
00313         {
00314         //Triggers the next step of the state machine (ERegisteringService)
00315         SelfComplete(); 
00316         }
00317         
00318 /*
00319 ============================================================================
00320 Callback from CSocketWriter on sending data completion
00321 ============================================================================
00322 */
00323 void CBluetoothResponder::WriteComplete(TInt aError)
00324         {
00325         if(aError == KErrNone)
00326                 {
00327                 //Informs the observer of sending data completion and trigger the next step of the state machine (EWaitingForData)
00328                 iRespObs.SendDataComplete(iHandle);             
00329                 SelfComplete();
00330                 }
00331         else
00332                 {
00333                 //informs the observer of the error and reset the state machine to the EIdle state                      
00334                 Cancel();
00335                 iState = EIdle;
00336                 iRespObs.ConnectionErr(iHandle, aError);
00337                 }
00338         }
00339 
00340 /*
00341 ============================================================================
00342 Callback from CSocketReader on receiving data completion
00343 ============================================================================
00344 */
00345 void CBluetoothResponder::ReportData(const TDesC8& aData, TInt aError)
00346         {               
00347         if(aError == KErrNone)
00348                 {
00349                 //Passes to the observer the data received from the remote device and trigger the next step
00350                 //of the state machine (EWaitingForData)
00351                 iRespObs.DataReceived(iHandle, aData);
00352                 SelfComplete();
00353                 }
00354         else
00355                 {                       
00356                 //Informs the observer of the error and reset the state machine to the EIdle state                      
00357                 Cancel();
00358                 iState = EIdle;
00359                 iRespObs.ConnectionErr(iHandle, aError);
00360                 }
00361         }
00362 
00363 /*
00364 ============================================================================
00365 Calls User::RequestComplete on this active object. Used to trigger the next step of the state machine.
00366 ============================================================================
00367 */
00368 void CBluetoothResponder::SelfComplete()
00369         {
00370         TRequestStatus* status = &iStatus;
00371         User::RequestComplete(status, KErrNone);
00372         SetActive();                    
00373         }
00374 
00375 /*
00376 ============================================================================
00377 Handles a leave occurring in the request completion event handler RunL().
00378 Close all active BT sockets, reset the state machine to the EIdle state and
00379 report the error to the observer
00380 ============================================================================
00381 */
00382 TInt CBluetoothResponder::RunError(TInt aError)
00383         {
00384         //Informs the observer of the error and reset the state machine.        
00385         iAcceptingSocket.Close();
00386         iListeningSocket.Close();
00387         iRespObs.ConnectionErr(iHandle, aError);
00388         iState = EIdle;
00389         return KErrNone;
00390         }

Generated by  doxygen 1.6.2