Symbian3/SDK/Source/GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita
changeset 0 89d6a7a84779
equal deleted inserted replaced
-1:000000000000 0:89d6a7a84779
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept xml:lang="en" id="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E"><title>Secure Simple Pairing (SSP)</title><prolog><metadata><keywords/></metadata></prolog><conbody><ul><li id="GUID-D51EB888-7908-5F75-80B7-06B47994F22B"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-226FB791-0EA7-5756-893F-2839D4178E1E">Introduction</xref>  </p> </li> <li id="GUID-F8B04B59-3A9B-54B5-9D64-A64F6A930A9E"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-2891BA26-F6C3-5F3C-A567-34D806A5DAA4">Overview</xref>  </p> </li> <li id="GUID-744E1DDF-2908-569D-9C7A-E29223C6C9E1"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-FC295A44-D8D9-5835-A895-BFB85C5CB8B8">Symbian support for SSP</xref>  </p> </li> <li id="GUID-2C9207CF-8924-568A-93F9-340AB3F2A1E4"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-E6541D2E-7881-5670-B0CF-F57AA64AC032">Implementing SSP notifiers</xref>  </p> </li> <li id="GUID-3703505F-4F60-534C-B492-D83002FA9577"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-E1A7D7D3-891E-5A90-926D-3F946A5448A3">Using the Out of Band API</xref>  </p> </li> <li id="GUID-67BC873E-DC42-5208-AE65-2564B1655C41"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-6C20C226-C4CE-5937-93D2-C1A89F00004C">Using the dedicated bonding API</xref>  </p> </li> </ul> <section id="GUID-226FB791-0EA7-5756-893F-2839D4178E1E"><title>Introduction</title> <p>Secure Simple Pairing, introduced into Bluetooth v2.1, simplifies the user experience when pairing Bluetooth devices. </p> <p>This document describes the Symbian OS implementation of SSP. It describes the tasks that must be performed by UI creators to implement SSP and it describes how application developers can use Symbian APIs to pair with Bluetooth enabled devices using SSP. </p> <p><b>Scope</b> </p> <p>This document is intended for Symbian partners and developers implementing SSP on Symbian OS. It assumes that you are familiar with Bluetooth and with developing on Symbian OS. </p> <p><b>Purpose of SSP</b> </p> <p>SSP was introduced to simplify the user experience when pairing Bluetooth devices. Specifically: </p> <ul><li id="GUID-63DD983D-4C9B-55A9-BC1E-B5F590576B51"><p>there is no need for the user to think of a number </p> </li> <li id="GUID-08AFD4B9-4B08-55CD-8A5A-83200F0D75AD"><p>the authentication process may differ for different devices and different services </p> </li> <li id="GUID-AC68A597-36ED-5FE4-8678-21FB8F4498BE"><p>all data transfer is encrypted </p> </li> </ul> </section> <section id="GUID-2891BA26-F6C3-5F3C-A567-34D806A5DAA4"><title>Overview</title> <p><b>The pairing model</b> </p> <p>Pre-SSP pairing is achieved by the user(s) entering a personal identification number (PIN) on one or both devices. Devices with no keypads, such as headsets, have their PINs (typically "0000" or "1234") hard-wired. This is now referred to as Legacy Paring. </p> <p>Under SSP, devices specify their authorisation requirements. The user may have to: </p> <ul><li id="GUID-4B260DAC-E745-5FBE-95D7-3FD721A3F960"><p>press a button in response to a simple yes or no query </p> </li> <li id="GUID-E73EB3E7-5DBC-5326-9728-E086AA58B05A"><p>compare two automatically generated numbers and select 'yes' if they match or 'no' if they do not </p> </li> <li id="GUID-C7AE53AC-037A-5171-AED1-62AB0F0A1953"><p>enter a number on one or both devices </p> </li> <li id="GUID-E4FF8EB0-D0DD-5C39-891E-9732F53B4D7E"><p>do nothing </p> </li> </ul> <p>Once the devices have paired the user may be asked to authorise bonding. Bonded devices can subsequently pair with no user interaction. </p> <p><b>Key concepts</b> </p> <dl><dlentry><dt> Authentication</dt> <dd><p>Verification that a remote device is what it claims to be. Authentication may be unnecessary for some pairings (see Just Works), may require user intervention (see Man in the Middle) or may be performed through another channel (see Out of Band). </p> </dd> </dlentry> <dlentry><dt> Authorisation</dt> <dd><p>In legacy pairing a remote device can be authorised after pairing such that it subsequently connects automatically without user intervention. Authorisation is on a per-service basis. See <b>bonding</b>. </p> </dd> </dlentry> <dlentry><dt>Encryption</dt> <dd><p>Transmission of data between devices after SSP is always encrypted. Under legacy pairing data transmission is not always encrypted. </p> </dd> </dlentry> <dlentry><dt> Man In The Middle (MITM) protection</dt> <dd><p>Authentication explicitly provided by the user before pairing can take place. Under SSP, devices and services have hard-wired authentication requirements as follows: MITM required, MITM not required (see Just Works) and MITM desired (subject to the user interface capabilities of the devices) </p> </dd> </dlentry> <dlentry><dt> Just Works</dt> <dd><p>For some pairings there is little risk of a security breach so SSP provides a mechanism for devices to pair with no explicit user authentication. </p> </dd> </dlentry> <dlentry><dt> Passkey</dt> <dd><p>In the context of a Symbian device, which always has both a display and a keypad, passkey authentication is used when pairing with a remote device which has a keypad but no display. The Symbian device displays a number which the user must enter using the keypad on the remote device </p> </dd> </dlentry> <dlentry><dt> Out Of Band (OOB)</dt> <dd><p>Out of Band authentication is performed using a non-Bluetooth communication channel. The data required to open an MITM protected Bluetooth connection with a remote device is transmitted by other means. </p> </dd> </dlentry> <dlentry><dt> Bonding</dt> <dd><p>Two devices may bond after athentication such that they can reconnect without user intervention. Bonding is achieved on a Symbian device by storing a link key. Symbian devices attempt to bond by default. The user or the remote device may specify that the devices do not bond. </p> </dd> </dlentry> <dlentry><dt> Link key</dt> <dd><p>When a connection is authenticated a link key is created. The link key indicates the strength of authentication (legacy, authenticated or unauthenticated). The link key may be stored by the Symbian device and used to bond (the default behaviour) or discarded when the connection ends. The link key is not displayed to the user. </p> </dd> </dlentry> </dl> </section> <section id="GUID-FC295A44-D8D9-5835-A895-BFB85C5CB8B8"><title>Symbian support for SSP</title> <p><b>Components</b> </p> <p>Support for SSP was added to Symbian OS in v9.5. </p> <p>Most of the changes are internal and transparent to system creators and developers. However, some new APIs added to the Bluetooth User Library allow application developers to use SSP features, and Licensees must implement some SSP specific notifiers. </p> <p>The diagram below shows the interfaces and interface classes required to implement SSP. </p> <p><b> Dedicated Bonding </b> </p> <p>Dedicated bonding is performed by the Bluetooth Pairing Server. Applications can use the <xref href="GUID-8E97F127-DA49-3BB6-B274-348138B425DF.dita"><apiname>RBluetoothDedicatedBondingInitiator</apiname></xref> API to request bonding with a specified Bluetooth device. </p> <p><b> Out of Band Data</b> </p> <p>Out of Band pairing data can be passed to the Bluetooth Pairing Server. The server can use the supplied data to pair with the specified device. Applications can also use the <xref href="GUID-C92BBABD-AE1B-325B-9791-95875272AAAC.dita"><apiname>RBluetoothOobData</apiname></xref> API to retrieve OOB data for the local device to be passed to remote devices. </p> <p><b> Numeric Comparison Notifier </b> </p> <p>The Bluetooth sub-system requires a Numeric Comparison Notifier to be provided by the UI. The notifier must handle <xref href="GUID-D3F5500E-2BCD-3BB9-8B6B-5716C22FAB05.dita"><apiname>TBTNumericComparisonParams</apiname></xref> and return a boolean value which indicates the user's decision. </p> <p><b> Passkey Entry Notifier </b> </p> <p>The Bluetooth sub-system requires a Passkey Entry Notifier to be provided by the UI. The notifier must handle <xref href="GUID-F4DBF857-2192-3177-B431-8499907E41AF.dita"><apiname>TBTPasskeyDisplayParams</apiname></xref> and <xref href="GUID-EB94B14B-F836-3FA1-88CD-51FC0528D76A.dita"><apiname>TBTPasskeyDisplayUpdateParams</apiname></xref>. </p> <p><b> Data Types </b> </p> <p>SSP specific data is stored and manipulated using the following types (significant functions and fields shown only). These types are used in various device and service related APIs. They are defined in <filepath>bt_sock.h</filepath> and <filepath>btdevice.h</filepath>. </p> <p> <codeph>#include &lt;bt_sock.h&gt; </codeph>  </p> <codeblock id="GUID-3CF4FEFE-96AC-5CF3-A522-397754161A50" xml:space="preserve">
       
    13 enum TBluetoothMitmProtection
       
    14     {
       
    15     EMitmNotRequired    = 0x0,   // No Man-in-the-Middle authentication is not required.
       
    16     EMitmDesired        = 0x1,      // Man-in-the-Middle authentication should be used where possible. 
       
    17     EMitmRequired        = 0x2      // Man-in-the-Middle authentication is required. 
       
    18     };
       
    19 </codeblock> <p> <xref href="GUID-C0341B1C-E358-3C7B-B673-37103E2AF0A3.dita"><apiname>TBTAccessRequirements</apiname></xref>  </p> <codeblock id="GUID-2EA4EA4A-AFC4-5BB2-851F-0891EC42FF6F" xml:space="preserve">
       
    20 class TBTAccessRequirements
       
    21     {
       
    22 public:
       
    23        ...
       
    24     IMPORT_C void                      SetAuthentication( TBluetoothMitmProtection aPreference );
       
    25     IMPORT_C TBluetoothMitmProtection  MitmProtection() const;
       
    26                 ...
       
    27 
       
    28     
       
    29 private:
       
    30     enum TBTServiceSecuritySettings
       
    31         {
       
    32         EAuthenticate = 0x01,
       
    33         EAuthorise = 0x02,
       
    34         EEncrypt = 0x04,
       
    35         EDenied = 0x08,
       
    36         EMitm = 0x30,      // 2 bit field for MITM
       
    37         };
       
    38     
       
    39     enum TBTAccessRequirementsMitmProtection
       
    40         {
       
    41         EAccessRequirementsMitmUndefined = 0x00,
       
    42         EAccessRequirementsMitmNotRequired = 0x10,
       
    43         EAccessRequirementsMitmDesired = 0x20,
       
    44         EAccessRequirementsMitmRequired = 0x30
       
    45         };
       
    46     };</codeblock> <p> <xref href="GUID-BC29B643-2CE8-30C1-BF41-4D2B5585DC81.dita"><apiname>TBTServiceSecurity</apiname></xref>  </p> <codeblock id="GUID-28168FA1-2CF7-59BE-B77B-484991491810" xml:space="preserve">
       
    47 class TBTServiceSecurity
       
    48     {
       
    49 public:
       
    50     ...
       
    51     IMPORT_C void                     SetAuthentication( TBluetoothMitmProtection aPreference );
       
    52     IMPORT_C TBool                    AuthenticationRequired() const;
       
    53     IMPORT_C TBluetoothMitmProtection MitmProtection() const;
       
    54     ...
       
    55     
       
    56 private:
       
    57     TBTAccessRequirements iSecurityRequirements;    // Whether the service requires authentication, authorisation, encryption or min passkey len.
       
    58     };
       
    59 
       
    60 typedef TPckgBuf&lt;TBTServiceSecurity&gt; TBTServiceSecurityPckg;    // Package definition for securty settings
       
    61 </codeblock> <p> <codeph>#include &lt;btdevice.h&gt; </codeph>  </p> <p> <xref href="GUID-7E0FA8C7-DEB4-3D86-901E-68DAC99DCA40.dita"><apiname>TBTDeviceSecurity</apiname></xref>  </p> <codeblock id="GUID-DCC63DB6-6D3F-5B32-836D-973E65305B13" xml:space="preserve">
       
    62 class TBTDeviceSecurity
       
    63     {
       
    64 public:
       
    65 
       
    66        // Enumeration to provide select MITM protection required. 
       
    67 
       
    68     enum TMitmRequired
       
    69         {
       
    70         EMitmUnspecified,      // No specific MITM protection requirements
       
    71         EMitmRequired          // Require the link is MITM protected 
       
    72         };
       
    73     
       
    74 public:
       
    75 
       
    76     ...
       
    77     IMPORT_C void          SetNoAuthenticate(TBool aDecision);
       
    78     IMPORT_C void          SetMitmRequirements(TMitmRequired aDecision);
       
    79     ...
       
    80     IMPORT_C TBool         NoAuthenticate() const;
       
    81     IMPORT_C TMitmRequired MitmRequirements() const;
       
    82     ...
       
    83 
       
    84 public:
       
    85     // Enumeration to assist in parsing of security settings.
       
    86     enum TBTDeviceSecuritySettings
       
    87         {
       
    88         ENoAuthenticate            = 0x01,        // Don't authenticate the link @deprecated
       
    89         ENoAuthorise            = 0x02,           // Don't authorise the connection
       
    90         EEncrypt                = 0x04,              // Encrypt the link
       
    91         EBanned                    = 0x08,              // Don't connect to the device
       
    92         EMitmProtectionRequired    = 0x10,  // Require the link is MITM protected
       
    93         };
       
    94     };
       
    95 </codeblock> </section> <section id="GUID-E6541D2E-7881-5670-B0CF-F57AA64AC032"><title>Implementing SSP notifiers</title> <p><b>Introdution</b> </p> <p>The Bluetooth sub-system has no user interface. It uses the Symbian <xref href="GUID-E049772D-A96F-592F-AF59-C9B69E8D24C1.dita">notifier framework</xref> for user interaction when pairing. The UI system must provide a notifier, in plug-in form, for each user interaction required by SSP. The notifier must receive data in a specified format from the Bluetooth sub-system, display appropriate controls in a dialog on the screen, respond to the user's input and send data back to the Bluetooth sub-system in a specified format. </p> <p>This document assumes that you already have Bluetooth notifiers in your system. It describes the key aspects of adding notifiers for SSP. The structures, types and constants described below are defined in <filepath>BTExtNotifiers.h</filepath>. You can add notifiers to an existing plug-in or create a new plug-in. </p> <p>Notifiers are typically implemented as sleeping dialogs. A sleeping dialog has its resources allocated when its application (in this case the Uikon Server) is started. A sleeping dialog can therefore be displayed (roused) safely under low memory conditions. </p> <p><b>Notes: </b> </p> <ul><li id="GUID-8F9A2CA6-0481-55EB-8458-076AA869CF1E"><p>This document does not describe how to implement an ECOM plug-in or a sleeping dialog. </p> </li> <li id="GUID-0BA5CB89-F09C-5150-82C5-2169503FF961"><p>Customisation Kit Licensees can find an example notifier implementation here: <filepath>sf/mw/classicui/commonuisupport/uikon/examples/notifier1/</filepath>  </p> </li> </ul> <p><b>Numeric Comparison Notifier</b> </p> <p>A numeric comparison notifier is required for SSP Man in the Middle (MITM) authentication when the remote device is capable of displaying a number to the the user and accepting a yes or no response from the user. The notifier must display an automatically generated number and invite the user to confirm (yes or no) that the number is the same as the number displayed on the remote device. The notifier must return the user's response. </p> <p>The Bluetooth Security Manager uses the following code to ask the notifier framework to display the Numeric Comparison Notifier </p> <codeblock id="GUID-C797A612-4AD7-5DE1-854E-3398945A4957" xml:space="preserve">
       
    96 
       
    97 // defined in header file(s)
       
    98 
       
    99 TBTDevAddr                      iDevAddr ;
       
   100 RNotifier                       iNotifier ;
       
   101 TUint32                         iNumericValue ;
       
   102 TBool                           iInternallyInitiated ;
       
   103 TBTNumericComparisonParamsPckg  iNumericComparisonParamsPckg ;
       
   104 TPckgBuf&lt;TBool&gt;                 iResultPckg ;
       
   105 // 
       
   106 
       
   107 void CBTNumericComparator::DoRequest()
       
   108    {
       
   109    // Start the RNotifier plugin that deals with authorisation.
       
   110 
       
   111    ...
       
   112 
       
   113    TBTDeviceName deviceName = KNullDesC ;
       
   114 
       
   115    iNumericComparisonParamsPckg = TBTNumericComparisonParams( iDevAddr, 
       
   116                                                               deviceName, 
       
   117                                                               iNumericValue, 
       
   118                                                               TBTNumericComparisonParams::ERemoteCanConfirm, 
       
   119                                                               iInternallyInitiated);
       
   120 
       
   121    iNotifier.StartNotifierAndGetResponse( iStatus, 
       
   122                                           KBTNumericComparisonNotifierUid, 
       
   123                                           iNumericComparisonParamsPckg, 
       
   124                                           iResultPckg);
       
   125    SetActive();
       
   126    }
       
   127 </codeblock> <p>From the code above you can see that the Numeric Comparision Notifier is identified by the UID<codeph>KBTNumericComparisonNotifierUid</codeph> and that it must handle data in <xref href="GUID-D3F5500E-2BCD-3BB9-8B6B-5716C22FAB05.dita"><apiname>TBTNumericComparisonParams</apiname></xref> (which is packaged into <codeph>TBTNumericComparisonParamsPckg</codeph> for inter-process transfer). </p> <p>The code fragment below shows how to extract the numeric comparison data within a notifier. </p> <p>NOTE: You will need to implement all of the virtual functions in <xref href="GUID-4E967403-417B-3340-B168-9FAF6565FEFF.dita"><apiname>MEikSrvNotifierBase2.</apiname></xref>  </p> <codeblock id="GUID-36408990-3292-531C-B15E-E88575CD0578" xml:space="preserve">
       
   128 class CNumericComparisonNotifier : public CEikDialog, public MEikSrvNotifierBase2
       
   129     {
       
   130 public:
       
   131 
       
   132     ...
       
   133 
       
   134     // from MEikSrvNotifierBase2
       
   135     void StartL ( const TDesC8&amp; aBuffer, TInt aReplySlot, const RMessagePtr2&amp; aMessage ) ;
       
   136  
       
   137     ...
       
   138 
       
   139     void Complete( TBool aDecision, TInt aReason ) ;
       
   140 
       
   141 private:
       
   142     TInt                iRepySlot ;
       
   143     TNotifierInfo       iInfo ;
       
   144     RMessage2           iMessage ;
       
   145     TBTNumeriComparisonParamsPckg     iNumericComparisonParamsPckg ;
       
   146     TBTDevAddr          iAddr ;
       
   147     TBTDeviceName       iName ;
       
   148     TUint32             iNumericalValue ;
       
   149 
       
   150     } ;
       
   151 
       
   152 
       
   153 
       
   154 //--------------------------------
       
   155 
       
   156 ...
       
   157 
       
   158 void CNumericComparisionNotifier::StartL( const TDesC8&amp; aBuffer, TInt aReplySlot, const RMessagePtr2&amp; aMessage )
       
   159     {
       
   160 
       
   161     iMessage = RMessage2( aMessage ) ;   // keep a copy ofthe message so that it can be completed later.
       
   162     iReplySlot = aReplySlot ;            // copy the reply slot too
       
   163 
       
   164     // Extract the comparison parameters from the buffer
       
   165 
       
   166     iNumericComparisonParamsPckg.Copy( aBuffer ) ; 
       
   167 
       
   168     iAddr           = iNumericComparisonParamsPckg().DeviceAddress() ;
       
   169     iName           = iNumericComparisonParamsPckg().DeviceName() ;
       
   170     iNumericalValue = iNumericComparisonParamsPckg().NumericalValue() ;
       
   171 
       
   172     ...
       
   173 
       
   174     RouseSleepingDialog() ; 
       
   175 
       
   176     }
       
   177         
       
   178 </codeblock> <p>Your dialog must display <codeph>iNumericalValue</codeph> and ask the user if the number displayed is the same as the number displayed on the other Bluetooth device. The user must be able to select 'Yes' or 'No'. </p> <p>The <codeph>StartL()</codeph> function above must return quickly so it must not wait for the user's response. Your notifier must complete the message (<codeph>iMessage</codeph>) as shown below when the user enters a response. </p> <codeblock id="GUID-7C313F8D-F521-541D-8294-686339633F43" xml:space="preserve">
       
   179 void CNumericComparisionNotifier::Complete( TBool aDecision, TInt aReason )
       
   180     {
       
   181     if ( aReason == KErrNone )
       
   182         {
       
   183         TInt err = iMessage.Write( iReplySlot, TPckgC&lt;TBool&gt;( aDecision ) ) ;
       
   184         iMessage.Complete( err ) ;
       
   185         }
       
   186      else
       
   187         {
       
   188         iMessage.Complete( aReason ) ;
       
   189         }
       
   190      }
       
   191 </codeblock> <p><b>Passkey Notifier</b> </p> <p>A passkey notifier is required for SSP MITM authentication when the user must type a number on a remote device which has a keypad and no display. The notifier displays the number that the user must type. In the code below the notifier also displays a '*' character as the user types each digit into the remote device. </p> <p>The Bluetooth Security Manager uses the following code to ask the Notifier Framework to display the passkey notifier. </p> <codeblock id="GUID-C9F126EB-D3F2-5F08-AF50-64123BB5455F" xml:space="preserve">
       
   192 
       
   193 // defined in header file(s)
       
   194 
       
   195 TBTDevAddr                      iDevAddr ;
       
   196 RNotifier                       iNotifier ;
       
   197 TUint32                         iNumericValue ;   // the passkey number
       
   198 TBool                           iInternallyInitiated ;
       
   199 TBTPasskeyDisplayParamsPckg     iPasskeyDisplayParamsPckg ;
       
   200 TBTDeviceNameUpdateParamsPckg   iDeviceNameUpdateParamsPckg;
       
   201 TBuf8&lt;1&gt;                        iResultPckg ;
       
   202 
       
   203 void CBTPasskeyEntry::DoRequest()
       
   204     {
       
   205     // Start the RNotifier plugin that deals with authorisation.
       
   206 
       
   207     ...
       
   208 
       
   209     TBTDeviceName deviceName ;    
       
   210     
       
   211     deviceName = KNullDesC ;
       
   212 
       
   213     iPasskeyDisplayParamsPckg = TBTPasskeyDisplayParams( iDevAddr, 
       
   214                                                          deviceName, 
       
   215                                                          iNumericValue, 
       
   216                                                          iInternallyInitiated ) ;
       
   217 
       
   218     iNotifier.StartNotifierAndGetResponse( iStatus, 
       
   219                                            KBTPasskeyDisplayNotifierUid, 
       
   220                                            iPasskeyDisplayParamsPckg, 
       
   221                                            iResultPckg ) ;
       
   222     SetActive() ;
       
   223 
       
   224     }
       
   225 
       
   226 </codeblock> <p>From the code above you can see that the Passkey Notifier is identified by the UID<codeph>KBTPasskeyNotifierUid</codeph> and that it must handle data in <xref href="GUID-F4DBF857-2192-3177-B431-8499907E41AF.dita"><apiname>TBTPasskeyDisplayParams</apiname></xref> (which is packaged into <codeph>TBTPasskeyDisplayParamsPckg</codeph> for inter-process transfer). </p> <p>As the user enters passkey digits into the remote device the Security Manager also uses <codeph>RNotifier::UpdateNotifierAndGetResponse()</codeph> to send <xref href="GUID-EB94B14B-F836-3FA1-88CD-51FC0528D76A.dita"><apiname>TBTPasskeyDisplayUpdateParams</apiname></xref> (packaged in <xref href="GUID-D6CA0DDB-1CD0-32F1-BBB5-7E280E1C4779.dita"><apiname>TBTPasskeyDisplayUdateParamsPckg</apiname></xref>) to the notifier. Your notifier must use this information to reflect the key presses on the remote device. </p> <p>The code fragment below shows how to extract the passkey data within a notifier. </p> <p>NOTE: You will need to implement all of the virtual functions in <xref href="GUID-4E967403-417B-3340-B168-9FAF6565FEFF.dita"><apiname>MEikSrvNotifierBase2.</apiname></xref>  </p> <codeblock id="GUID-B38F7512-B091-5F93-86F1-EA740DAD7509" xml:space="preserve">
       
   227 class CPasskeyNotifier : public CEikDialog, public MEikSrvNotifierBase2
       
   228     {
       
   229 public:
       
   230 
       
   231     ...
       
   232 
       
   233     // from MEikSrvNotifierBase2
       
   234     void   StartL( const TDesC8&amp; aBuffer, TInt aReplySlot, const RMessagePtr2&amp; aMessage ) ;
       
   235     TPtrC8 UpdateL( const TDesC8&amp; aBuffer ) ;  // new information 
       
   236 
       
   237     ...
       
   238 
       
   239 private:
       
   240     TInt                            iRepySlot ;
       
   241     TNotifierInfo                   iInfo ;
       
   242     RMessage2                       iMessage ;
       
   243     TBTPasskeyDisplayParamsPckg     iPasskeyDisplayParamsPckg ;
       
   244     TBTDevAddr                      iAddr ;
       
   245     TBTDeviceName                   iName ;
       
   246     TUint32                         iNumericalValue ;   // the passkey number
       
   247 
       
   248     } ;
       
   249 
       
   250 //--------------------------------
       
   251 
       
   252 ...
       
   253 
       
   254 void CPasskeyNotifier::StartL( const TDesC8&amp; aBuffer, TInt aReplySlot, const RMessagePtr2&amp; aMessage )
       
   255     {
       
   256 
       
   257     iMessage = RMessage2(aMessage);  // keep a copy ofthe message so that it can be completed later.  
       
   258     iReplySlot = aReplySlot ;  // copy the reply slot too
       
   259 
       
   260     // Extract the comparison parameters from the buffer
       
   261 
       
   262     iPasskeyDisplayParamsPckg.Copy( aBuffer ) ;
       
   263 
       
   264     iAddr           = iPasskeyDisplayParamsPckg().DeviceAddress() ;
       
   265     iName           = iPasskeyDisplayParamsPckg().DeviceName() ;
       
   266     iNumericValue   = iPasskeyDisplayParamsPckg().NumericalValue() ;
       
   267 
       
   268 
       
   269     ...
       
   270 
       
   271     RouseSleepingDialog() ;  // display the passkey 
       
   272 
       
   273     ...
       
   274 
       
   275     }
       
   276 
       
   277 void CPasskeyNotifier::UpdateL( const TDesC8&amp; aBuffer )
       
   278     {
       
   279 
       
   280     // extract the contents of the buffer
       
   281 
       
   282     TBTNotifierUpdateParamsPckg2 pckgRaw ;
       
   283     pckgRaw.Copy( aBuffer.Left( pckgRaw.MaxLength() ) ) ;
       
   284 
       
   285     // update the dialog to reflect the keys pressed on the remote device
       
   286 
       
   287     if ( pckgRaw().Type() == TBTNotifierUpdateParams2::EPasskeyDisplay )
       
   288         {
       
   289         TBTPasskeyDisplayUpdateParamsPckg pckg ;
       
   290         pckg.Copy( aBuffer ) ;
       
   291         HCIPasskeyEntryNotificationType keypressNotification = pckg().KeypressNotification() ;
       
   292 
       
   293         switch (keypressNotification)
       
   294             {
       
   295         case EPasskeyEntryStarted :
       
   296             {
       
   297             break ;
       
   298             }
       
   299         case EPasskeyDigitEntered :
       
   300             {
       
   301             // display '*'
       
   302             break ;
       
   303             }
       
   304         case EPasskeyDigitDeleted :
       
   305             {
       
   306             // remove '*', reposition cursor
       
   307             break ;
       
   308             }
       
   309         case EPasskeyCleared :
       
   310             {
       
   311             // clear display, reposition cursor
       
   312             break ;
       
   313             }
       
   314         case EPasskeyEntryCompleted :
       
   315             {
       
   316             // hide the dialog
       
   317             ExitSleepingDialog() ;
       
   318             break;
       
   319             }
       
   320         default :
       
   321             break ;
       
   322         }
       
   323     else if( pckgRaw().Type() == TBTNotifierUpdateParams2::EDeviceName )
       
   324         {
       
   325         // handle name update
       
   326         }
       
   327     return KNullDesC8() ;
       
   328     }
       
   329 
       
   330 
       
   331 
       
   332 </codeblock> </section> <section id="GUID-E1A7D7D3-891E-5A90-926D-3F946A5448A3"><title>Out of Band (OOB) authentication</title> <p><b>Introduction</b> </p> <p>Out of Band authentication is achieved using a communication method other than Bluetooth. Once OOB authentication has succeeded an encrypted Bluetooth channel is opened between the two devices. </p> <p>The OOB API, <xref href="GUID-C92BBABD-AE1B-325B-9791-95875272AAAC.dita"><apiname>RBluetoothOobData</apiname></xref>, allows an application handling OOB authentication to provide pairing information for a remote device. </p> <p> <xref href="GUID-C92BBABD-AE1B-325B-9791-95875272AAAC.dita"><apiname>RBluetoothOobData</apiname></xref> allows an application handling OOB authentication to retrieve pairing information for the local device. </p> <p><b>Using the OOB API</b> </p> <p>The OOB data API is provided by the Pairing Server (part of the Security Manager). </p> <codeblock id="GUID-B474C4DA-7FBE-5ABF-9124-BF1B3A899EE0" xml:space="preserve">
       
   333 
       
   334 #include &lt;pairing.h&gt;
       
   335 
       
   336     RBluetoothPairingServer pairingServer ;
       
   337     RBluetoothOobData       OobData ;
       
   338 
       
   339 
       
   340     // Connect to the Pairing server 
       
   341 
       
   342     TInt err = pairingServer.connect() ;
       
   343 
       
   344     // Paring session
       
   345 
       
   346     err = OobData.Open( iPairingServer ) ;
       
   347 
       
   348 
       
   349     // Use the API pass hash and randomizer values to and from the pairing server.
       
   350    
       
   351     ...
       
   352 
       
   353 
       
   354     // Tidy up
       
   355 
       
   356     OobData.Close() ;
       
   357     PairingServer.Close() ;
       
   358 
       
   359 </codeblock> <p>The API has three primary functions: </p> <p> <codeph>RefreshLocalOobData()</codeph> - This function causes the Bluetooth controller to generate new hash and randomizer values for the local device. To retrieve the new values call <codeph>ReadLocalOobData()</codeph>  </p> <p> <codeph>ReadLocalOobData()</codeph> - This function returns the hash and randomizer values that the Bluetooth controller is currently using. </p> <p> <codeph>ProvideRemoteOobData()</codeph> - Use this function to pass OOB data about a remote device to the Bluetooth sub-system. Three versions of the function are available which take slightly different parameters. Information provided using one of these functions can be cleared using <codeph>ClearRemoteOobData()</codeph>. </p> </section> <section id="GUID-6C20C226-C4CE-5937-93D2-C1A89F00004C"><title>Dedicated bonding</title> <p><b>Introduction</b> </p> <p>Dedicated bonding is intended for applications which bond with a specific Bluetooth device. </p> <p><b>Using the dedicated bonding API</b> </p> <codeblock id="GUID-BA1AF395-EFB7-5E12-9E94-D83504876401" xml:space="preserve">
       
   360 
       
   361 #include &lt;pairing.h&gt;
       
   362 
       
   363     RBluetoothPairingServer             pairingServer ;
       
   364     RBluetoothDedicatedBondingInitiator bonder ;
       
   365     TBTDevAddr                          addr ;
       
   366     TRequstStatus                       status ;
       
   367 
       
   368 
       
   369     // Connect to the Pairing server 
       
   370 
       
   371     TInt err = pairingServer.connect() ;
       
   372 
       
   373 
       
   374     // Use the Bluetooth address of the remote device bonder.Start( pairingServer, addr, status ) ;
       
   375 
       
   376 
       
   377     // Wait for the request to complete
       
   378 
       
   379     User::WaitForRequest(status);
       
   380 
       
   381 
       
   382     // Close the connection with the bonder (Must be closed before bonding with another device)
       
   383 
       
   384     bonder.Close();
       
   385 
       
   386     pairingServer.Close() ;
       
   387 
       
   388           </codeblock> </section> </conbody></concept>