Symbian3/SDK/Source/GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Fri, 11 Jun 2010 12:39:03 +0100
changeset 8 ae94777fff8f
parent 7 51a74ef9ed63
child 13 48780e181b38
permissions -rw-r--r--
Week 23 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 2714, Bug 462.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E" xml:lang="en"><title>Secure
Simple Pairing (SSP)</title><shortdesc>Describes SSP.</shortdesc><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
platform 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 platform. It assumes that you are familiar with
Bluetooth and with developing on Symbian platform. </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>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">
enum TBluetoothMitmProtection
    {
    EMitmNotRequired    = 0x0,   // No Man-in-the-Middle authentication is not required.
    EMitmDesired        = 0x1,      // Man-in-the-Middle authentication should be used where possible. 
    EMitmRequired        = 0x2      // Man-in-the-Middle authentication is required. 
    };
</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">
class TBTAccessRequirements
    {
public:
       ...
    IMPORT_C void                      SetAuthentication( TBluetoothMitmProtection aPreference );
    IMPORT_C TBluetoothMitmProtection  MitmProtection() const;
                ...

    
private:
    enum TBTServiceSecuritySettings
        {
        EAuthenticate = 0x01,
        EAuthorise = 0x02,
        EEncrypt = 0x04,
        EDenied = 0x08,
        EMitm = 0x30,      // 2 bit field for MITM
        };
    
    enum TBTAccessRequirementsMitmProtection
        {
        EAccessRequirementsMitmUndefined = 0x00,
        EAccessRequirementsMitmNotRequired = 0x10,
        EAccessRequirementsMitmDesired = 0x20,
        EAccessRequirementsMitmRequired = 0x30
        };
    };</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">
class TBTServiceSecurity
    {
public:
    ...
    IMPORT_C void                     SetAuthentication( TBluetoothMitmProtection aPreference );
    IMPORT_C TBool                    AuthenticationRequired() const;
    IMPORT_C TBluetoothMitmProtection MitmProtection() const;
    ...
    
private:
    TBTAccessRequirements iSecurityRequirements;    // Whether the service requires authentication, authorisation, encryption or min passkey len.
    };

typedef TPckgBuf&lt;TBTServiceSecurity&gt; TBTServiceSecurityPckg;    // Package definition for securty settings
</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">
class TBTDeviceSecurity
    {
public:

       // Enumeration to provide select MITM protection required. 

    enum TMitmRequired
        {
        EMitmUnspecified,      // No specific MITM protection requirements
        EMitmRequired          // Require the link is MITM protected 
        };
    
public:

    ...
    IMPORT_C void          SetNoAuthenticate(TBool aDecision);
    IMPORT_C void          SetMitmRequirements(TMitmRequired aDecision);
    ...
    IMPORT_C TBool         NoAuthenticate() const;
    IMPORT_C TMitmRequired MitmRequirements() const;
    ...

public:
    // Enumeration to assist in parsing of security settings.
    enum TBTDeviceSecuritySettings
        {
        ENoAuthenticate            = 0x01,        // Don't authenticate the link @deprecated
        ENoAuthorise            = 0x02,           // Don't authorise the connection
        EEncrypt                = 0x04,              // Encrypt the link
        EBanned                    = 0x08,              // Don't connect to the device
        EMitmProtectionRequired    = 0x10,  // Require the link is MITM protected
        };
    };
</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-GENID-1-10-1-3-1-1-4-1-4-1.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">

// defined in header file(s)

TBTDevAddr                      iDevAddr ;
RNotifier                       iNotifier ;
TUint32                         iNumericValue ;
TBool                           iInternallyInitiated ;
TBTNumericComparisonParamsPckg  iNumericComparisonParamsPckg ;
TPckgBuf&lt;TBool&gt;                 iResultPckg ;
// 

void CBTNumericComparator::DoRequest()
   {
   // Start the RNotifier plugin that deals with authorisation.

   ...

   TBTDeviceName deviceName = KNullDesC ;

   iNumericComparisonParamsPckg = TBTNumericComparisonParams( iDevAddr, 
                                                              deviceName, 
                                                              iNumericValue, 
                                                              TBTNumericComparisonParams::ERemoteCanConfirm, 
                                                              iInternallyInitiated);

   iNotifier.StartNotifierAndGetResponse( iStatus, 
                                          KBTNumericComparisonNotifierUid, 
                                          iNumericComparisonParamsPckg, 
                                          iResultPckg);
   SetActive();
   }
</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">
class CNumericComparisonNotifier : public CEikDialog, public MEikSrvNotifierBase2
    {
public:

    ...

    // from MEikSrvNotifierBase2
    void StartL ( const TDesC8&amp; aBuffer, TInt aReplySlot, const RMessagePtr2&amp; aMessage ) ;
 
    ...

    void Complete( TBool aDecision, TInt aReason ) ;

private:
    TInt                iRepySlot ;
    TNotifierInfo       iInfo ;
    RMessage2           iMessage ;
    TBTNumeriComparisonParamsPckg     iNumericComparisonParamsPckg ;
    TBTDevAddr          iAddr ;
    TBTDeviceName       iName ;
    TUint32             iNumericalValue ;

    } ;



//--------------------------------

...

void CNumericComparisionNotifier::StartL( const TDesC8&amp; aBuffer, TInt aReplySlot, const RMessagePtr2&amp; aMessage )
    {

    iMessage = RMessage2( aMessage ) ;   // keep a copy ofthe message so that it can be completed later.
    iReplySlot = aReplySlot ;            // copy the reply slot too

    // Extract the comparison parameters from the buffer

    iNumericComparisonParamsPckg.Copy( aBuffer ) ; 

    iAddr           = iNumericComparisonParamsPckg().DeviceAddress() ;
    iName           = iNumericComparisonParamsPckg().DeviceName() ;
    iNumericalValue = iNumericComparisonParamsPckg().NumericalValue() ;

    ...

    RouseSleepingDialog() ; 

    }
        
</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">
void CNumericComparisionNotifier::Complete( TBool aDecision, TInt aReason )
    {
    if ( aReason == KErrNone )
        {
        TInt err = iMessage.Write( iReplySlot, TPckgC&lt;TBool&gt;( aDecision ) ) ;
        iMessage.Complete( err ) ;
        }
     else
        {
        iMessage.Complete( aReason ) ;
        }
     }
</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">

// defined in header file(s)

TBTDevAddr                      iDevAddr ;
RNotifier                       iNotifier ;
TUint32                         iNumericValue ;   // the passkey number
TBool                           iInternallyInitiated ;
TBTPasskeyDisplayParamsPckg     iPasskeyDisplayParamsPckg ;
TBTDeviceNameUpdateParamsPckg   iDeviceNameUpdateParamsPckg;
TBuf8&lt;1&gt;                        iResultPckg ;

void CBTPasskeyEntry::DoRequest()
    {
    // Start the RNotifier plugin that deals with authorisation.

    ...

    TBTDeviceName deviceName ;    
    
    deviceName = KNullDesC ;

    iPasskeyDisplayParamsPckg = TBTPasskeyDisplayParams( iDevAddr, 
                                                         deviceName, 
                                                         iNumericValue, 
                                                         iInternallyInitiated ) ;

    iNotifier.StartNotifierAndGetResponse( iStatus, 
                                           KBTPasskeyDisplayNotifierUid, 
                                           iPasskeyDisplayParamsPckg, 
                                           iResultPckg ) ;
    SetActive() ;

    }

</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">
class CPasskeyNotifier : public CEikDialog, public MEikSrvNotifierBase2
    {
public:

    ...

    // from MEikSrvNotifierBase2
    void   StartL( const TDesC8&amp; aBuffer, TInt aReplySlot, const RMessagePtr2&amp; aMessage ) ;
    TPtrC8 UpdateL( const TDesC8&amp; aBuffer ) ;  // new information 

    ...

private:
    TInt                            iRepySlot ;
    TNotifierInfo                   iInfo ;
    RMessage2                       iMessage ;
    TBTPasskeyDisplayParamsPckg     iPasskeyDisplayParamsPckg ;
    TBTDevAddr                      iAddr ;
    TBTDeviceName                   iName ;
    TUint32                         iNumericalValue ;   // the passkey number

    } ;

//--------------------------------

...

void CPasskeyNotifier::StartL( const TDesC8&amp; aBuffer, TInt aReplySlot, const RMessagePtr2&amp; aMessage )
    {

    iMessage = RMessage2(aMessage);  // keep a copy ofthe message so that it can be completed later.  
    iReplySlot = aReplySlot ;  // copy the reply slot too

    // Extract the comparison parameters from the buffer

    iPasskeyDisplayParamsPckg.Copy( aBuffer ) ;

    iAddr           = iPasskeyDisplayParamsPckg().DeviceAddress() ;
    iName           = iPasskeyDisplayParamsPckg().DeviceName() ;
    iNumericValue   = iPasskeyDisplayParamsPckg().NumericalValue() ;


    ...

    RouseSleepingDialog() ;  // display the passkey 

    ...

    }

void CPasskeyNotifier::UpdateL( const TDesC8&amp; aBuffer )
    {

    // extract the contents of the buffer

    TBTNotifierUpdateParamsPckg2 pckgRaw ;
    pckgRaw.Copy( aBuffer.Left( pckgRaw.MaxLength() ) ) ;

    // update the dialog to reflect the keys pressed on the remote device

    if ( pckgRaw().Type() == TBTNotifierUpdateParams2::EPasskeyDisplay )
        {
        TBTPasskeyDisplayUpdateParamsPckg pckg ;
        pckg.Copy( aBuffer ) ;
        HCIPasskeyEntryNotificationType keypressNotification = pckg().KeypressNotification() ;

        switch (keypressNotification)
            {
        case EPasskeyEntryStarted :
            {
            break ;
            }
        case EPasskeyDigitEntered :
            {
            // display '*'
            break ;
            }
        case EPasskeyDigitDeleted :
            {
            // remove '*', reposition cursor
            break ;
            }
        case EPasskeyCleared :
            {
            // clear display, reposition cursor
            break ;
            }
        case EPasskeyEntryCompleted :
            {
            // hide the dialog
            ExitSleepingDialog() ;
            break;
            }
        default :
            break ;
        }
    else if( pckgRaw().Type() == TBTNotifierUpdateParams2::EDeviceName )
        {
        // handle name update
        }
    return KNullDesC8() ;
    }



</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">

#include &lt;pairing.h&gt;

    RBluetoothPairingServer pairingServer ;
    RBluetoothOobData       OobData ;


    // Connect to the Pairing server 

    TInt err = pairingServer.connect() ;

    // Paring session

    err = OobData.Open( iPairingServer ) ;


    // Use the API pass hash and randomizer values to and from the pairing server.
   
    ...


    // Tidy up

    OobData.Close() ;
    PairingServer.Close() ;

</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">

#include &lt;pairing.h&gt;

    RBluetoothPairingServer             pairingServer ;
    RBluetoothDedicatedBondingInitiator bonder ;
    TBTDevAddr                          addr ;
    TRequstStatus                       status ;


    // Connect to the Pairing server 

    TInt err = pairingServer.connect() ;


    // Use the Bluetooth address of the remote device bonder.Start( pairingServer, addr, status ) ;


    // Wait for the request to complete

    User::WaitForRequest(status);


    // Close the connection with the bonder (Must be closed before bonding with another device)

    bonder.Close();

    pairingServer.Close() ;

          </codeblock> </section>
</conbody></concept>