examples/sfexamples/RockPaperScissorsGameSourceCode_S60/RPS/src/BluetoothServiceAdvertiser.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 
00031 // INCLUDE FILES
00032 #include "BluetoothServiceAdvertiser.h"
00033 #include "common.hrh"
00034 
00035 _LIT(KRpsServiceName, "RPS");
00036 _LIT(KRpsServiceDes, "RPS");
00037 
00038 const TInt KPortBufMaxSize = 2;
00039 const TInt KServAvailBufMaxSize = 1;
00040 
00041 /*
00042 ============================================================================
00043 CBluetoothServiceAdvertiser's constructor
00044 ============================================================================
00045 */
00046 CBluetoothServiceAdvertiser::CBluetoothServiceAdvertiser(MBluetoothServiceAdvertiserObserver& aSerAdvObs)
00047         :CActive(CActive::EPriorityStandard), iSerAdvObs(aSerAdvObs), iState(EIdle)
00048         {
00049         CActiveScheduler::Add(this);
00050         }
00051 
00052 /*
00053 ============================================================================
00054 CBluetoothServiceAdvertiser's destructor
00055 ============================================================================
00056 */
00057 CBluetoothServiceAdvertiser::~CBluetoothServiceAdvertiser()
00058         {
00059         Cancel();
00060         UnregisterService();
00061         }
00062 
00063 /*
00064 ============================================================================
00065 Entry point of the CBluetoothServiceAdvertiser's state machine. The initial state must be EIdle.
00066 A state other than EIdle will result in a KErrInUse. This is to prevent StartL() calling
00067 more than once if the state machine is alread active.
00068 ============================================================================
00069 */
00070 void CBluetoothServiceAdvertiser::StartL(const TInt aPort)
00071         {
00072         if (iState != EIdle)
00073                 {
00074                 User::Leave(KErrInUse);
00075                 }
00076                 
00077         iPort = aPort;
00078         SelfComplete();
00079         }
00080 
00081 /*
00082 ============================================================================
00083 Connect to the SDP server and open a SDP's  RSdpDatabase subsession where 
00084 service records and their attributes can be added, deleted, and updated.
00085 ============================================================================
00086 */
00087 void CBluetoothServiceAdvertiser::ConnectToSdpL()
00088         {
00089         iState = EConnecting;
00090         User::LeaveIfError(iSdpServ.Connect());
00091         User::LeaveIfError(iSdpDatabase.Open(iSdpServ));
00092         SelfComplete();
00093         }
00094         
00095 /*
00096 ============================================================================
00097 Create and add the RPS's service record into the SDP's database
00098 ============================================================================
00099 */
00100 void CBluetoothServiceAdvertiser::BuildServiceRecordL()
00101         {
00102         iState = EBuildingServiceRecord;
00103         TUUID serviceUUID(KRPS_BTServiceID);
00104         //Creates a new service record, with a single service class (KRPS_BTServiceID) in the SDP database.
00105         //If succesful iRecordHandle will hold the RPS's record handle.
00106         iSdpDatabase.CreateServiceRecordL(serviceUUID, iRecordHandle);
00107 
00108         //Now the RPS's record needs to be filled with RPS's service attributes
00109         
00110         // Add the RFCOMM protocol attribute to the record.
00111         CSdpAttrValueDES* protocolDescriptorList = CSdpAttrValueDES::NewDESL(NULL);
00112         CleanupStack::PushL(protocolDescriptorList);
00113 
00114     TBuf8<KPortBufMaxSize> port; 
00115     port.Append((TChar)iPort);
00116     
00117     //Builds a protocol list of attributes. In our example the list contains only the RFCOMM protocol element
00118     //and the RFCOMM's port. For more information about the structure of a SDP's record please refer to the SDK
00119         protocolDescriptorList
00120         ->StartListL()                                  //Marks the start of the list
00121             ->BuildDESL()                               //Adds a Data Element Sequence (DES) 
00122                 ->StartListL()                          //Indicates that subsequent elements added belong to a DES (Data Element Sequence) or DEA (Data Element Alternative)
00123                         ->BuildUUIDL(KRFCOMM)   //Adds the RFCOMM's TUUID
00124                 ->BuildUintL(port)              //Adds the RFCOMM's port. Remote devices will connect to this port to use the RPS's service
00125                 ->EndListL()                            //Marks the end of the subsequent element
00126         ->EndListL();                                   //Marks the end of the list
00127 
00128 
00129         //Sets the protocol list to the record
00130         iSdpDatabase.UpdateAttributeL(iRecordHandle, KSdpAttrIdProtocolDescriptorList, *protocolDescriptorList);
00131         CleanupStack::PopAndDestroy(protocolDescriptorList);
00132 
00133         //Adds the record's name attribute
00134         iSdpDatabase.UpdateAttributeL(iRecordHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName, KRpsServiceName);
00135 
00136         //Adds the record's description attribute
00137         iSdpDatabase.UpdateAttributeL(iRecordHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceDescription, KRpsServiceDes);
00138 
00139         //Adds the record's available service attribute
00140         CSdpAttrValue* attrVal = NULL;
00141         TBuf8<KServAvailBufMaxSize> avail;
00142         avail.FillZ(1);
00143         avail[0]=0xff;//Fully available value
00144         //Service availability is store as a TUint 
00145         attrVal = CSdpAttrValueUint::NewUintL(avail);
00146         CleanupStack::PushL(attrVal);
00147         iSdpDatabase.UpdateAttributeL(iRecordHandle, KSdpAttrIdServiceAvailability, *attrVal);
00148         CleanupStack::PopAndDestroy(attrVal);
00149         SelfComplete();
00150         }
00151         
00152 /*
00153 ============================================================================
00154 Removes the RPS's service record from the SDP's database
00155 ============================================================================
00156 */
00157 void CBluetoothServiceAdvertiser::UnregisterService()
00158         {
00159         // Deletes SDP Record
00160     if (iRecordHandle)
00161                 {
00162         TRAPD(ret,iSdpDatabase.DeleteRecordL(iRecordHandle));
00163                 }
00164     // Closes SDP's database handle
00165     iSdpDatabase.Close();
00166     // Close SDP's session
00167     iSdpServ.Close();
00168         }
00169         
00170 /*
00171 ============================================================================
00172 Handles the active object's service advertising completion events.
00173 ============================================================================
00174 */
00175 void CBluetoothServiceAdvertiser::RunL()
00176         {
00177         switch (iState)
00178         {
00179         case EIdle:
00180                 //State machine entry point
00181                 ConnectToSdpL();
00182                 break;
00183         case EConnecting:
00184                 //Connect to SDP server completed, start building the RPS's service record
00185                 BuildServiceRecordL();
00186             break;  
00187         case EBuildingServiceRecord:
00188                 //Build RPS's service record completed, notify the completion event to the observer.
00189                 iSerAdvObs.AdvertiserComplete();
00190             break;   
00191         default:
00192             User::Leave(KErrCorrupt);
00193             break;
00194         };      
00195         }
00196 
00197 /*
00198 ============================================================================
00199 DoCancel is called as part of the active object's Cancel().
00200 ============================================================================
00201 */
00202 void CBluetoothServiceAdvertiser::DoCancel()
00203         {
00204         //Not Used
00205         }
00206 
00207 /*
00208 ============================================================================
00209 Calls User::RequestComplete on this active object. Used to trigger the next step of the state machine.
00210 ============================================================================
00211 */
00212 void CBluetoothServiceAdvertiser::SelfComplete()
00213         {
00214         TRequestStatus* status = &iStatus;
00215         User::RequestComplete(status, KErrNone);
00216         SetActive();            
00217         }
00218 
00219 /*
00220 ============================================================================
00221 Handles a leave occurring in the request completion event handler RunL().
00222 Close all resources, reset the state machine to the EIdle state, notify the
00223 observer of the error
00224 ============================================================================
00225 */
00226 TInt CBluetoothServiceAdvertiser::RunError(TInt aError)
00227         {
00228         switch (iState)
00229         {
00230         case EConnecting:
00231             break;
00232         case EBuildingServiceRecord:
00233                     // Delete SDP Record
00234                     if (iRecordHandle)
00235                                 {
00236                         TRAPD(err,iSdpDatabase.DeleteRecordL(iRecordHandle));
00237                                 }
00238                     // Close SDP handles
00239                     iSdpDatabase.Close();
00240                     iSdpServ.Close();
00241             break;   
00242         default:
00243                 aError = KErrCorrupt;
00244             break;
00245         };
00246                 
00247         iState = EIdle;
00248         iSerAdvObs.ReportAdvertiserErr(aError);
00249         return KErrNone;
00250         }

Generated by  doxygen 1.6.2