examples/SFExamples/RockPaperScissorsGameSourceCode_S60/RPS/src/BluetoothManager.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 "rpsgamescreens.h"
00031 #include "BluetoothManager.h"
00032 #include "BluetoothDeviceDiscoverer.h"
00033 #include "BluetoothConnector.h"
00034 #include "common.hrh"
00035 
00036 // -----------------------------------------------------------------------------------
00037 // CBluetoothManager class
00038 // -----------------------------------------------------------------------------------
00039 CBluetoothManager* CBluetoothManager::NewL(CGameScreenManager& aGameScreenMgr)
00040         {
00041         CBluetoothManager* me = new (ELeave) CBluetoothManager(aGameScreenMgr);
00042         CleanupStack::PushL(me);
00043         me->ConstructL();
00044         CleanupStack::Pop(me);
00045         return (me);
00046         }
00047 
00048 void CBluetoothManager::ConstructL()
00049         {
00050         // Get socket server session
00051         User::LeaveIfError(iSocketServer.Connect());
00052         iBtDeviceDiscoverer = CBluetoothDeviceDiscoverer::NewL(*this);
00053         }
00054 
00055 CBluetoothManager::CBluetoothManager(CGameScreenManager& aGameScreenMgr)
00056 : iGameScreenMgr(aGameScreenMgr)
00057         {
00058         TUUID targetServiceClass(KRPS_BTServiceID);
00059         //Use by the RNotifier dialog to get only BT devices that supports the RPS's service
00060         iDevSelFilter.SetUUID(targetServiceClass);
00061         }
00062 
00063 CBluetoothManager::~CBluetoothManager()
00064         {
00065         if(iBtConnBase)
00066                 {               
00067                 iBtConnBase->Cancel();
00068                 delete iBtConnBase;
00069                 }
00070         
00071         if (iBtDeviceDiscoverer)
00072                 {
00073                 iBtDeviceDiscoverer->Cancel();
00074                 delete iBtDeviceDiscoverer;
00075                 }
00076         
00077         iSocketServer.Close();
00078         
00079         //iBtConnBaseArray.ResetAndDestroy();//Not used for 2 player multiplay, see header file for details
00080         }
00081 
00082 /*
00083 ============================================================================
00084 Callback from the Control Screen. The player has decided to control the game.
00085 The CRpsGameEngine takes the Master role of the game.
00086 ============================================================================
00087 */
00088 void CBluetoothManager::StartBtMaster()
00089         {
00090         iGameScreenMgr.GameData().iRpsError = KErrNone;
00091         
00092         //Display the Connecting screen
00093         iGameScreenMgr.SetGameState(CGameScreenManager::ENotifierScreen);
00094         
00095         //Start BT device discovery
00096         TBTDeviceSelectionParamsPckg pckg(iDevSelFilter);
00097         TRAPD(err, iBtDeviceDiscoverer->DiscoverAndSelectDeviceL(pckg));
00098         if(err!=KErrNone)
00099                 {
00100                 DisplayError(err);
00101                 }
00102         }
00103 
00104 /*
00105 ============================================================================
00106 Callback from the Control Screen. The player has decided to wait for a connection.
00107 The CRpsGameEngine takes the Slave role of the game.
00108 ============================================================================
00109 */
00110 void CBluetoothManager::StartBtSlave()
00111         {
00112         iGameScreenMgr.GameData().iRpsError = KErrNone;
00113         
00114         //Display the Waiting Screen
00115         iGameScreenMgr.SetGameState(CGameScreenManager::EWaitConnScreen);
00116         
00117         ASSERT(!iBtConnBase);
00118         
00119         TRAPD(err, iBtConnBase = CBluetoothResponder::NewL(*this, iSocketServer);
00120                            iBtConnBase->StartL());
00121 
00122         if(err != KErrNone)
00123                 {
00124                 if(iBtConnBase)
00125                         {
00126                         delete iBtConnBase;
00127                         iBtConnBase = NULL;
00128                         }
00129                 DisplayError(err);                      
00130                 }
00131         }
00132 
00133 /*
00134 ============================================================================
00135 Quit the game either because the player decided to exit the game (KErrNone)
00136 or because an error occurred during the game                                       
00137 ============================================================================
00138 */
00139 void CBluetoothManager::QuitMultiplayerGame()
00140         {
00141         iConnected = EFalse;
00142 
00143         if(iBtConnBase)
00144                 {                       
00145                 iBtConnBase->Cancel();
00146                 delete iBtConnBase;
00147                 iBtConnBase = NULL;
00148                 }
00149         }
00150 
00151 
00152 /*
00153 ============================================================================
00154 Master kick off the game.
00155 ============================================================================
00156 */
00157 void CBluetoothManager::StartGame()
00158         {
00159         //We assume only the Master can start the game since it's the one that controls the game.
00160         ASSERT(iBtConnBase);
00161         ASSERT(iBtConnBase->Master());
00162 
00163         if(iConnected)
00164                 {
00165                 //Send the control flag EPlay to the slave asking to start the game     
00166                 TPckgBuf<TRpsData> rpsData;
00167                 rpsData().iRpsControl = TRpsData::EPlay;
00168                 iBtConnBase->SendData(rpsData);
00169                 // Reset the game data before play starts
00170                 iGameScreenMgr.Roshambo().ResetPlayers();
00171                 //Show the play screen
00172                 iGameScreenMgr.SetGameState(CGameScreenManager::EPlayScreen);
00173                 }
00174         }
00175 
00176 /*
00177 ============================================================================
00178 Start another session of the game.
00179 ============================================================================
00180 */
00181 void CBluetoothManager::ReplayGame()
00182         {
00183         //Master and Slave restart the game
00184         ASSERT(iBtConnBase);    
00185         if(iConnected)
00186                 {
00187                 if(iBtConnBase->Master())
00188                         {
00189                         //Master displays the Start Screen
00190                         iGameScreenMgr.SetGameState(CGameScreenManager::EStartScreen);  
00191                         }
00192                 else
00193                         {
00194                         //Slave displays the Wait Start Screen
00195                         iGameScreenMgr.SetGameState(CGameScreenManager::EWaitStartScreen);              
00196                         }
00197                 }
00198         }
00199 
00200 /*
00201 ============================================================================
00202 Send the RPS's player choice to the remote BT device. On completion calls SendDataComplete()
00203 ============================================================================
00204 */
00205 void CBluetoothManager::SendData(TRoshambo::TElement aElement)
00206         {
00207         //Note that the code here to send the data to the remote device is the same for the 
00208         //Master and slave. Change the code to be like ReplayGame() above if your multiplayer game needs to handle
00209         //the Master and Slave differently.     
00210         if(iConnected)
00211                 {
00212                 TPckgBuf<TRpsData> rpsData;
00213                 rpsData().iElement = aElement;
00214                 rpsData().iRpsControl = TRpsData::EElement;
00215 
00216                 //Since the sending is an asynchronous operation we need to cache the local player's choice
00217                 iGameScreenMgr.Roshambo().SetLocalPlayer(aElement);
00218                 // Now wait for the opponent to choose
00219                 iGameScreenMgr.SetGameState(CGameScreenManager::EWaitOpponentScreen);
00220                 iBtConnBase->SendData(rpsData);
00221                 }
00222         }
00223 
00224 /*
00225 ============================================================================
00226 Query function to see if Master/Slave are connected 
00227 ============================================================================
00228 */
00229 TBool CBluetoothManager::Connected()
00230         {
00231         return iConnected;      
00232         }
00233 
00234 /*
00235 ============================================================================
00236 RNotifier's callback. aResponse contains the player's selected BT device
00237 ============================================================================
00238 */
00239 void CBluetoothManager::OnDeviceDiscoveryComplete(const TBTDeviceResponseParamsPckg& aResponse)
00240         {
00241         iGameScreenMgr.SetGameState(CGameScreenManager::EConnectingScreen);
00242         iBtDevAddr = aResponse().BDAddr();
00243         
00244         if(iBtConnBase)
00245                 {
00246                 iBtConnBase->Cancel();
00247                 delete iBtConnBase;
00248                 iBtConnBase = NULL;
00249                 }
00250         
00251         //It's important to note that in a multiplayer game with more then two players, the engine needs to create an
00252         //array of iBtConnBase, one for each Master<->Slave connection in the BT piconet. The BT piconet contains
00253         //the BT devices (Slaves) selected by the player (Master). RHostResolver needs to be use instead of RNotifier 
00254         //if your application needs to select more then two BT devices at one time. A customized UI needs also to be
00255         //implemented to show the player and the available BT devices (s)he can select.The engine needs also to manage
00256         //the bidirectional communication between the Master<->Slaves and SlaveN<->Master<->SlaveM.
00257   
00258         TRAPD(err, StartConnectorL());
00259         if(err != KErrNone)
00260                 {
00261                 delete iBtConnBase;
00262                 iBtConnBase = NULL;
00263                 DisplayError(err);
00264                 }               
00265         }
00266 
00267 void CBluetoothManager::StartConnectorL()
00268         {
00269         iBtConnBase = CBluetoothConnector::NewL(*this, iSocketServer, iBtDevAddr);
00270     iBtConnBase->StartL();
00271         }
00272 /*
00273 ============================================================================
00274 Callback from CBluetoothDeviceDiscoverer if an error occur during device discovery
00275 ============================================================================
00276 */
00277 void CBluetoothManager::OnDeviceDiscoveryErr(const TInt aError)
00278         {
00279         DisplayError(aError);
00280         }
00281 
00282 /*
00283 ============================================================================
00284 Callback either from the Connector or Responder to report a connection error
00285 ============================================================================
00286 */
00287 void CBluetoothManager::ConnectionErr(const TInt /*aConnHandle*/, const TInt aError)
00288         {
00289         //See RpsGameEngine.h to see how your multiplayer game could use aConnHandle
00290         if(aError == KErrNone)
00291                 {
00292                 //KErrNone means succesful connection
00293                 iConnected = ETrue;
00294                 //Master and Slave need to take different action at this point
00295                 ASSERT(iBtConnBase);
00296                 if(iBtConnBase->Master())
00297                         {                       
00298                         iGameScreenMgr.SetGameState(CGameScreenManager::EStartScreen);
00299                         }
00300                 else
00301                         {
00302                         iGameScreenMgr.SetGameState(CGameScreenManager::EWaitStartScreen);      
00303                         }
00304                 }
00305         else
00306                 {
00307                 QuitMultiplayerGame();
00308                 DisplayError(aError);
00309                 }
00310         }
00311 
00312 /*
00313 ============================================================================
00314 Callback either from the Connector or Responder to report incoming data from the remote BT device
00315 ============================================================================
00316 */
00317 void CBluetoothManager::DataReceived(const TInt /*aConnHandle*/, const TDesC8& aData)
00318         {
00319         //See RpsGameEngine.h to see how your multiplayer game could use aConnHandle
00320         TPckgBuf<TRpsData> rpsData;
00321         rpsData.Copy(aData);
00322         if(rpsData().iRpsControl == TRpsData::EPlay)
00323                 {
00324                 //We assume that only the Responder deals with game's control flags.
00325                 ASSERT(!iBtConnBase->Master());
00326                 iGameScreenMgr.Roshambo().ResetPlayers();
00327                 //Start the game by displaying the Play Screen
00328                 iGameScreenMgr.SetGameState(CGameScreenManager::EPlayScreen);
00329                 }
00330         else if(rpsData().iRpsControl == TRpsData::EElement)
00331                 {
00332                 TPckgBuf<TRpsData> rpsData;
00333                 rpsData.Copy(aData);
00334                 if(iGameScreenMgr.Roshambo().LocalPlayer() != TRoshambo::EInvalid)
00335                         {
00336                         //Player already sent the rps's element, display the result.
00337                         iGameScreenMgr.Roshambo().SetOpponent(rpsData().iElement);      
00338                         iGameScreenMgr.SetGameState(CGameScreenManager::EResultScreen);
00339                         }
00340                 else
00341                         {
00342                         //Cache the opponent element and wait for the player
00343                         iGameScreenMgr.Roshambo().SetOpponent(rpsData().iElement);
00344                         }
00345                 }
00346         }
00347 
00348 /*
00349 ============================================================================
00350 Callback either from the Connector or Responder to report the sending data completion
00351 ============================================================================
00352 */
00353 void CBluetoothManager::SendDataComplete(const TInt /*aConnHandle*/)
00354         {               
00355         //See RpsGameEngine.h to see how your multiplayer game could use aConnHandle
00356         //We already cached the local player's move
00357         if(iGameScreenMgr.Roshambo().Opponent() != TRoshambo::EInvalid)
00358                 {
00359                 //Opponent already submitted the move, so result can be calculated and displayed
00360                 iGameScreenMgr.SetGameState(CGameScreenManager::EResultScreen);
00361                 }
00362         }
00363 
00364 void CBluetoothManager::DisplayError(TInt aError)
00365         {
00366         iGameScreenMgr.GameData().iRpsError = aError;
00367         iGameScreenMgr.SetGameState(CGameScreenManager::EErrorScreen);  
00368         }
00369 

Generated by  doxygen 1.6.2