Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Библиотека для работы с Bluetooth

01.01.2007
package BTClasses;
 
{$R *.res}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION ON}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES OFF}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$IMPLICITBUILD OFF}
 
requires
  rtl
;
 
contains
 
BTRadio in 'BTRadio.pas',
 
BluetoothAPI in 'BluetoothAPI.pas',
 
BthSdpDef in 'BthSdpDef.pas',
 
BTExceptions in 'BTExceptions.pas',
 
BTStrings in 'BTStrings.pas',
 
BTDevice in 'BTDevice.pas';
 
end.
unit BluetoothAPI;
 
interface
 
uses
 
Windows, BthSdpDef;
 
const
  BLUETOOTH_MAX_NAME_SIZE            
= 248;
 
{$EXTERNALSYM BLUETOOTH_MAX_NAME_SIZE}
  BLUETOOTH_MAX_PASSKEY_SIZE        
= 16;
 
{$EXTERNALSYM BLUETOOTH_MAX_PASSKEY_SIZE}
  BLUETOOTH_MAX_PASSKEY_BUFFER_SIZE  
= BLUETOOTH_MAX_PASSKEY_SIZE + 1;
 
{$EXTERNALSYM BLUETOOTH_MAX_PASSKEY_BUFFER_SIZE}
 
// ***************************************************************************
//
//  Bluetooth Address
//
// ***************************************************************************
 
type
  BTH_ADDR
= Int64;
 
{$EXTERNALSYM BTH_ADDR}
 
  _BLUETOOTH_ADDRESS
= record
   
case Integer of
     
0: (ullLong: BTH_ADDR);       //  easier to compare again BLUETOOTH_NULL_ADDRESS
     
1: (rgBytes: array [0..5] of Byte);   //  easier to format when broken out
 
end;
 
{$EXTERNALSYM _BLUETOOTH_ADDRESS}
  BLUETOOTH_ADDRESS
= _BLUETOOTH_ADDRESS;
 
{$EXTERNALSYM BLUETOOTH_ADDRESS}
 
TBlueToothAddress = BLUETOOTH_ADDRESS;
 
PBlueToothAddress = ^BLUETOOTH_ADDRESS;
 
const
  BLUETOOTH_NULL_ADDRESS
: TBlueToothAddress = (ullLong: 0;);
 
{$EXTERNALSYM BLUETOOTH_NULL_ADDRESS}
 
// ***************************************************************************
//
//  Radio Enumeration
//
//  Description:
//      This group of APIs enumerates the installed Bluetooth radios.
//
//  Sample Usage:
//      HANDLE hRadio;
//      BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) };
//
//      HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio( &btfrp, &hRadio );
//      if ( NULL != hFind )
//      {
//          do
//          {
//              //
//              //  TODO: Do something with the radio handle.
//              //
//
//              CloseHandle( hRadio );
//
//          } while( BluetoothFindNextRadio( hFind, &hRadio ) );
//
//          BluetoothFindRadioClose( hFind );
//      }
//
// ***************************************************************************
 
type
  _BLUETOOTH_FIND_RADIO_PARAMS
= record
    dwSize
: DWORD;             //  IN  sizeof this structure
 
end;
 
{$EXTERNALSYM _BLUETOOTH_FIND_RADIO_PARAMS}
  BLUETOOTH_FIND_RADIO_PARAMS
= _BLUETOOTH_FIND_RADIO_PARAMS;
 
{$EXTERNALSYM BLUETOOTH_FIND_RADIO_PARAMS}
 
TBlueToothFindRadioParams = BLUETOOTH_FIND_RADIO_PARAMS;
 
PBlueToothFindRadioParams = ^BLUETOOTH_FIND_RADIO_PARAMS;
 
  HBLUETOOTH_RADIO_FIND
= THandle;
 
{$EXTERNALSYM HBLUETOOTH_RADIO_FIND}
 
//
//  Description:
//      Begins the enumeration of local Bluetooth radios.
//
//  Parameters:
//      pbtfrp
//          A pointer to a BLUETOOTH_FIND_RADIO_PARAMS structure. The dwSize
//          member of this structure must match the sizeof the of the structure.
//
//      phRadio
//          A pointer where the first radio HANDLE enumerated will be returned.
//
//  Return Values:
//      NULL
//          Error opening radios or no devices found. Use GetLastError() for
//          more info.
//
//          ERROR_INVALID_PARAMETER
//              pbtfrp parameter is NULL.
//
//          ERROR_REVISION_MISMATCH
//              The pbtfrp structure is not the right length.
//
//          ERROR_OUTOFMEMORY
//              Out of memory.
//
//          other Win32 errors.
//
//      any other
//          Success. The return handle is valid and phRadio points to a valid handle.
//
 
function BluetoothFindFirstRadio(const pbtfrp: PBlueToothFindRadioParams; var phRadio: THandle): HBLUETOOTH_RADIO_FIND; stdcall;
{$EXTERNALSYM BluetoothFindFirstRadio}
 
//
//  Description:
//      Finds the next installed Bluetooth radio.
//
//  Parameters:
//      hFind
//          The handle returned by BluetoothFindFirstRadio().
//
//      phRadio
//          A pointer where the next radio HANDLE enumerated will be returned.
//
//  Return Values:
//      TRUE
//          Next device succesfully found. pHandleOut points to valid handle.
//
//      FALSE
//          No device found. pHandleOut points to an invalid handle. Call
//          GetLastError() for more details.
//
//          ERROR_INVALID_HANDLE
//              The handle is NULL.
//
//          ERROR_NO_MORE_ITEMS
//              No more radios found.
//
//          ERROR_OUTOFMEMORY
//              Out of memory.
//
//          other Win32 errors
//
 
function BluetoothFindNextRadio(hFind: HBLUETOOTH_RADIO_FIND; var phRadio: THandle): BOOL; stdcall;
{$EXTERNALSYM BluetoothFindNextRadio}
 
//
//  Description:
//      Closes the enumeration handle.
//
//  Parameters
//      hFind
//          The handle returned by BluetoothFindFirstRadio().
//
//  Return Values:
//      TRUE
//          Handle succesfully closed.
//
//      FALSE
//          Failure. Check GetLastError() for details.
//
//          ERROR_INVALID_HANDLE
//              The handle is NULL.
//
 
function BluetoothFindRadioClose(hFind: HBLUETOOTH_RADIO_FIND): BOOL; stdcall;
{$EXTERNALSYM BluetoothFindRadioClose}
 
// ***************************************************************************
//
//  Radio Information
//
// ***************************************************************************
 
type
  _BLUETOOTH_RADIO_INFO
= record
    dwSize
: DWORD;                               // Size, in bytes, of this entire data structure
    address
: BLUETOOTH_ADDRESS;                  // Address of the local radio
    szName
: array [0..BLUETOOTH_MAX_NAME_SIZE - 1] of WideChar;    // Name of the local radio
    ulClassofDevice
: ULONG;                      // Class of device for the local radio
    lmpSubversion
: Word;                       // lmpSubversion, manufacturer specifc.
    manufacturer
: Word;                        // Manufacturer of the radio, BTH_MFG_Xxx value.  For the most up to date
                                               
// list, goto the Bluetooth specification website and get the Bluetooth
                                               
// assigned numbers document.
 
end;
 
{$EXTERNALSYM _BLUETOOTH_RADIO_INFO}
  BLUETOOTH_RADIO_INFO
= _BLUETOOTH_RADIO_INFO;
 
{$EXTERNALSYM BLUETOOTH_RADIO_INFO}
  PBLUETOOTH_RADIO_INFO
= ^BLUETOOTH_RADIO_INFO;
 
{$EXTERNALSYM PBLUETOOTH_RADIO_INFO}
 
TBlueToothRadioFind = BLUETOOTH_RADIO_INFO;
 
PBlueToothRadioFind = PBLUETOOTH_RADIO_INFO;
 
//
//  Description:
//      Retrieves the information about the radio represented by the handle.
//
//  Parameters:
//      hRadio
//          Handle to a local radio retrieved through BluetoothFindFirstRadio()
//          et al or SetupDiEnumerateDeviceInterfaces()
//
//      pRadioInfo
//          Radio information to be filled in. The dwSize member must match the
//          size of the structure.
//
//  Return Values:
//      ERROR_SUCCESS
//          The information was retrieved successfully.
//
//      ERROR_INVALID_PARAMETER
//          pRadioInfo or hRadio is NULL.
//
//      ERROR_REVISION_MISMATCH
//          pRadioInfo->dwSize is invalid.
//
//      other Win32 error codes.
//
 
function BluetoothGetRadioInfo(hRadio: THandle; var pRadioInfo: BLUETOOTH_RADIO_INFO): DWORD; stdcall;
{$EXTERNALSYM BluetoothGetRadioInfo}
 
// ***************************************************************************
//
//  Device Information Stuctures
//
// ***************************************************************************
 
type
  _BLUETOOTH_DEVICE_INFO
= record
    dwSize
: DWORD;                             //  size, in bytes, of this structure - must be the sizeof(BLUETOOTH_DEVICE_INFO)
   
Address: BLUETOOTH_ADDRESS;                  //  Bluetooth address
    ulClassofDevice
: ULONG;                    //  Bluetooth "Class of Device"
    fConnected
: BOOL;                         //  Device connected/in use
    fRemembered
: BOOL;                        //  Device remembered
    fAuthenticated
: BOOL;                     //  Device authenticated/paired/bonded
    stLastSeen
: SYSTEMTIME;                     //  Last time the device was seen
    stLastUsed
: SYSTEMTIME;                     //  Last time the device was used for other than RNR, inquiry, or SDP
    szName
: array [0..BLUETOOTH_MAX_NAME_SIZE - 1] of WideChar;  //  Name of the device
 
end;
 
{$EXTERNALSYM _BLUETOOTH_DEVICE_INFO}
  BLUETOOTH_DEVICE_INFO
= _BLUETOOTH_DEVICE_INFO;
 
{$EXTERNALSYM BLUETOOTH_DEVICE_INFO}
  PBLUETOOTH_DEVICE_INFO
= BLUETOOTH_DEVICE_INFO;
 
{$EXTERNALSYM PBLUETOOTH_DEVICE_INFO}
 
TBlueToothDeviceInfo = BLUETOOTH_DEVICE_INFO;
 
PBlueToothDeviceInfo = PBLUETOOTH_DEVICE_INFO;
 
// ***************************************************************************
//
//  Device Enumeration
//
//  Description:
//      Enumerates the Bluetooth devices. The types of returned device depends
//      on the flags set in the BLUETOOTH_DEVICE_SEARCH_PARAMS (see structure
//      definition for details).
//
//  Sample Usage:
//      HBLUETOOTH_DEVICE_FIND hFind;
//      BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = { sizeof(btsp) };
//      BLUETOOTH_DEVICE_INFO btdi = { sizeof(btdi) };
//
//      btsp.fReturnAuthenticated = TRUE;
//      btsp.fReturnRemembered    = TRUE;
//
//      hFind = BluetoothFindFirstDevice( &btsp, &btdi );
//      if ( NULL != hFind )
//      {
//          do
//          {
//              //
//              //  TODO:   Do something useful with the device info.
//              //
//
//          } while( BluetoothFindNextDevice( hFind, &btdi ) );
//
//          BluetoothFindDeviceClose( hFind );
//      }
//
// ***************************************************************************
 
type
  _BLUETOOTH_DEVICE_SEARCH_PARAMS
= record
    dwSize
: DWORD;                 //  IN  sizeof this structure
 
    fReturnAuthenticated
: BOOL;   //  IN  return authenticated devices
    fReturnRemembered
: BOOL;      //  IN  return remembered devices
    fReturnUnknown
: BOOL;         //  IN  return unknown devices
    fReturnConnected
: BOOL;       //  IN  return connected devices
 
    fIssueInquiry
: BOOL;          //  IN  issue a new inquiry
    cTimeoutMultiplier
: UCHAR;     //  IN  timeout for the inquiry
 
    hRadio
: THandle;                 //  IN  handle to radio to enumerate - NULL == all radios will be searched
 
end;
 
{$EXTERNALSYM _BLUETOOTH_DEVICE_SEARCH_PARAMS}
  BLUETOOTH_DEVICE_SEARCH_PARAMS
= _BLUETOOTH_DEVICE_SEARCH_PARAMS;
 
{$EXTERNALSYM BLUETOOTH_DEVICE_SEARCH_PARAMS}
 
TBlueToothDeviceSearchParams = BLUETOOTH_DEVICE_SEARCH_PARAMS;
 
  HBLUETOOTH_DEVICE_FIND
= THandle;
 
{$EXTERNALSYM HBLUETOOTH_DEVICE_FIND}
 
//
//  Description:
//      Begins the enumeration of Bluetooth devices.
//
//  Parameters:
//      pbtsp
//          A pointer to a BLUETOOTH_DEVICE_SEARCH_PARAMS structure. This
//          structure contains the flags and inputs used to conduct the search.
//          See BLUETOOTH_DEVICE_SEARCH_PARAMS for details.
//
//      pbtdi
//          A pointer to a BLUETOOTH_DEVICE_INFO structure to return information
//          about the first Bluetooth device found. Note that the dwSize member
//          of the structure must be the sizeof(BLUETOOTH_DEVICE_INFO) before
//          calling because the APIs hast to know the size of the buffer being
//          past in. The dwSize member must also match the exact
//          sizeof(BLUETOOTH_DEVICE_INFO) or the call will fail.
//
//  Return Values:
//      NULL
//          Error opening radios or not devices found. Use GetLastError for more info.
//
//          ERROR_INVALID_PARAMETER
//              pbtsp parameter or pbtdi parameter is NULL.
//
//          ERROR_REVISION_MISMATCH
//              The pbtfrp structure is not the right length.
//
//          other Win32 errors
//
//      any other value
//          Success. The return handle is valid and pbtdi points to valid data.
//
 
function BluetoothFindFirstDevice(const pbtsp: BLUETOOTH_DEVICE_SEARCH_PARAMS; var pbtdi: BLUETOOTH_DEVICE_INFO): HBLUETOOTH_DEVICE_FIND; stdcall;
{$EXTERNALSYM BluetoothFindFirstDevice}
 
//
//  Description:
//      Finds the next Bluetooth device in the enumeration.
//
//  Parameters:
//      hFind
//          The handle returned from BluetoothFindFirstDevice().
//
//      pbtdi
//          A pointer to a BLUETOOTH_DEVICE_INFO structure to return information
//          about the first Bluetooth device found. Note that the dwSize member
//          of the structure must be the sizeof(BLUETOOTH_DEVICE_INFO) before
//          calling because the APIs hast to know the size of the buffer being
//          past in. The dwSize member must also match the exact
//          sizeof(BLUETOOTH_DEVICE_INFO) or the call will fail.
//
//  Return Values:
//      TRUE
//          Next device succesfully found. pHandleOut points to valid handle.
//
//      FALSE
//          No device found. pHandleOut points to an invalid handle. Call
//          GetLastError() for more details.
//
//          ERROR_INVALID_HANDLE
//              The handle is NULL.
//
//          ERROR_NO_MORE_ITEMS
//              No more radios found.
//
//          ERROR_OUTOFMEMORY
//              Out of memory.
//
//          other Win32 errors
//
 
function BluetoothFindNextDevice(hFind: HBLUETOOTH_DEVICE_FIND; var pbtdi: BLUETOOTH_DEVICE_INFO): BOOL; stdcall;
{$EXTERNALSYM BluetoothFindNextDevice}
 
//
//  Description:
//      Closes the enumeration handle.
//
//  Parameters:
//      hFind
//          The handle returned from BluetoothFindFirstDevice().
//
//  Return Values:
//      TRUE
//          Handle succesfully closed.
//
//      FALSE
//          Failure. Check GetLastError() for details.
//
//          ERROR_INVALID_HANDLE
//              The handle is NULL.
//
 
function BluetoothFindDeviceClose(hFind: HBLUETOOTH_DEVICE_FIND): BOOL; stdcall;
{$EXTERNALSYM BluetoothFindDeviceClose}
 
//
//  Description:
//      Retrieves information about a remote device.
//
//      Fill in the dwSize and the Address members of the pbtdi structure
//      being passed in. On success, the rest of the members will be filled
//      out with the information that the system knows.
//
//  Parameters:
//      hRadio
//          Handle to a local radio retrieved through BluetoothFindFirstRadio()
//          et al or SetupDiEnumerateDeviceInterfaces()
//
//      pbtdi
//          A pointer to a BLUETOOTH_DEVICE_INFO structure to return information
//          about the first Bluetooth device found. The dwSize member of the
//          structure must be the sizeof the structure in bytes. The Address
//          member must be filled out with the Bluetooth address of the remote
//          device.
//
//  Return Values:
//      ERROR_SUCCESS
//          Success. Information returned.
//
//      ERROR_REVISION_MISMATCH
//          The size of the BLUETOOTH_DEVICE_INFO isn't compatible. Check
//          the dwSize member of the BLUETOOTH_DEVICE_INFO structure you
//          passed in.
//
//      ERROR_NOT_FOUND
//          The radio is not known by the system or the Address field of
//          the BLUETOOTH_DEVICE_INFO structure is all zeros.
//
//      ERROR_INVALID_PARAMETER
//          pbtdi is NULL.
//
//      other error codes
//
 
function BluetoothGetDeviceInfo(hRadio: THandle; var pbtdi: BLUETOOTH_DEVICE_INFO): DWORD; stdcall;
{$EXTERNALSYM BluetoothGetDeviceInfo}
 
//
//  Description:
//      Updates the computer local cache about the device.
//
//  Parameters:
//      pbtdi
//          A pointer to the BLUETOOTH_DEVICE_INFO structure to be updated.
//          The following members must be valid:
//              dwSize
//                  Must match the size of the structure.
//              Address
//                  Must be a previously found radio address.
//              szName
//                  New name to be stored.
//
//  Return Values:
//      ERROR_SUCCESS
//          The device information was updated successfully.
//
//      ERROR_INVALID_PARAMETER
//          pbtdi is NULL.
//
//      ERROR_REVISION_MISMATCH
//          pbtdi->dwSize is invalid.
//
//      other Win32 error codes.
//
 
function BluetoothUpdateDeviceRecord(var pbtdi: BLUETOOTH_DEVICE_INFO): DWORD; stdcall;
{$EXTERNALSYM BluetoothUpdateDeviceRecord}
 
//
//  Description:
//      Delete the authentication (aka "bond") between the computer and the
//      device. Also purges any cached information about the device.
//
//  Return Values:
//      ERROR_SUCCESS
//          The device was removed successfully.
//
//      ERROR_NOT_FOUND
//          The device was not found. If no Bluetooth radio is installed,
//          the devices could not be enumerated or removed.
//
 
function BluetoothRemoveDevice(var pAddress: BLUETOOTH_ADDRESS): DWORD; stdcall;
{$EXTERNALSYM BluetoothRemoveDevice}
 
// ***************************************************************************
//
//  Device Picker Dialog
//
//  Description:
//      Invokes a common dialog for selecting Bluetooth devices. The list
//      of devices displayed to the user is determined by the flags and
//      settings the caller specifies in the BLUETOOTH_SELECT_DEVICE_PARAMS
//      (see structure definition for more details).
//
//      If BluetoothSelectDevices() returns TRUE, the caller must call
//      BluetoothSelectDevicesFree() or memory will be leaked within the
//      process.
//
//  Sample Usage:
//
//      BLUETOOTH_SELECT_DEVICE_PARAMS btsdp = { sizeof(btsdp) };
//
//      btsdp.hwndParent = hDlg;
//      btsdp.fShowUnknown = TRUE;
//      btsdp.fAddNewDeviceWizard = TRUE;
//
//      BOOL b = BluetoothSelectDevices( &btsdp );
//      if ( b )
//      {
//          BLUETOOTH_DEVICE_INFO * pbtdi = btsdp.pDevices;
//          for ( ULONG cDevice = 0; cDevice < btsdp.cNumDevices; cDevice ++ )
//          {
//              if ( pbtdi->fAuthenticated || pbtdi->fRemembered )
//              {
//                  //
//                  //  TODO:   Do something usefull with the device info
//                  //
//              }
//
//              pbtdi = (BLUETOOTH_DEVICE_INFO *) ((LPBYTE)pbtdi + pbtdi->dwSize);
//          }
//
//          BluetoothSelectDevicesFree( &btsdp );
//      }
//
// ***************************************************************************
 
type
  _BLUETOOTH_COD_PAIRS
= record
    ulCODMask
: ULONG;                          //  ClassOfDevice mask to compare
    pcszDescription
: LPWSTR;                    //  Descriptive string of mask
 
end;
 
{$EXTERNALSYM _BLUETOOTH_COD_PAIRS}
  BLUETOOTH_COD_PAIRS
= _BLUETOOTH_COD_PAIRS;
 
{$EXTERNALSYM BLUETOOTH_COD_PAIRS}
 
TBlueToothCodPairs = BLUETOOTH_COD_PAIRS;
 
PBlueToothCodPairs = ^BLUETOOTH_COD_PAIRS;
 
  PFN_DEVICE_CALLBACK
= function(pvParam: Pointer; pDevice: PBLUETOOTH_DEVICE_INFO): BOOL; stdcall;
 
{$EXTERNALSYM PFN_DEVICE_CALLBACK}
 
  _BLUETOOTH_SELECT_DEVICE_PARAMS
= record
    dwSize
: DWORD;                             //  IN  sizeof this structure
 
    cNumOfClasses
: ULONG;                      //  IN  Number in prgClassOfDevice - if ZERO search for all devices
    prgClassOfDevices
: PBlueToothCodPairs;    //  IN  Array of CODs to find.
 
    pszInfo
: LPWSTR;                            //  IN  If not NULL, sets the "information" text
 
    hwndParent
: HWND;                         //  IN  parent window - NULL == no parent
 
    fForceAuthentication
: BOOL;               //  IN  If TRUE, authenication will be forced before returning
    fShowAuthenticated
: BOOL;                 //  IN  If TRUE, authenticated devices will be shown in the picker
    fShowRemembered
: BOOL;                    //  IN  If TRUE, remembered devices will be shown in the picker
    fShowUnknown
: BOOL;                       //  IN  If TRUE, unknown devices that are not authenticated or "remember" will be shown.
 
    fAddNewDeviceWizard
: BOOL;                //  IN  If TRUE, invokes the add new device wizard.
    fSkipServicesPage
: BOOL;                  //  IN  If TRUE, skips the "Services" page in the wizard.
 
    pfnDeviceCallback
: PFN_DEVICE_CALLBACK;      //  IN  If non-NULL, a callback that will be called for each device. If the
                                               
//      the callback returns TRUE, the item will be added. If the callback is
                                               
//      is FALSE, the item will not be shown.
    pvParam
: Pointer;                            //  IN  Parameter to be passed to pfnDeviceCallback as the pvParam.
 
    cNumDevices
: DWORD;                        //  IN  number calles wants - ZERO == no limit.
                                               
//  OUT the number of devices returned.
 
    pDevices
: PBLUETOOTH_DEVICE_INFO;           //  OUT pointer to an array for BLUETOOTH_DEVICE_INFOs.
                                               
//      call BluetoothSelectDevicesFree() to free
 
end;
 
{$EXTERNALSYM _BLUETOOTH_SELECT_DEVICE_PARAMS}
  BLUETOOTH_SELECT_DEVICE_PARAMS
= _BLUETOOTH_SELECT_DEVICE_PARAMS;
 
{$EXTERNALSYM BLUETOOTH_SELECT_DEVICE_PARAMS}
 
TBlueToothSelectDeviceParams = BLUETOOTH_SELECT_DEVICE_PARAMS;
 
PBlueToothSelectDeviceParams = ^BLUETOOTH_SELECT_DEVICE_PARAMS;
 
//
//  Description:
//      (See header above)
//
//  Return Values:
//      TRUE
//          User selected a device. pbtsdp->pDevices points to valid data.
//          Caller should check the fAuthenticated && fRemembered flags to
//          determine which devices we successfuly authenticated or valid
//          selections by the user.
//
//          Use BluetoothSelectDevicesFree() to free the nessecary data
//          such as pDevices only if this function returns TRUE.
//
//      FALSE
//          No valid data returned. Call GetLastError() for possible details
//          of the failure. If GLE() is:
//
//          ERROR_CANCELLED
//              The user cancelled  the request.
//
//          ERROR_INVALID_PARAMETER
//              The pbtsdp is NULL.
//
//          ERROR_REVISION_MISMATCH
//              The structure passed in as pbtsdp is of an unknown size.
//
//          other WIN32 errors
//
 
function BluetoothSelectDevices(pbtsdp: PBlueToothSelectDeviceParams): BOOL; stdcall;
{$EXTERNALSYM BluetoothSelectDevices}
 
//
//  Description:
//      This function should only be called if BluetoothSelectDevices() returns
//      TRUE. This function will free any memory and resource returned by the
//      BluetoothSelectDevices() in the BLUETOOTH_SELECT_DEVICE_PARAMS
//      structure.
//
//  Return Values:
//      TRUE
//          Success.
//
//      FALSE
//          Nothing to free.
//
 
function BluetoothSelectDevicesFree(pbtsdp: PBlueToothSelectDeviceParams): BOOL; stdcall;
{$EXTERNALSYM BluetoothSelectDevicesFree}
 
// ***************************************************************************
//
//  Device Property Sheet
//
// ***************************************************************************
 
//
//  Description:
//      Invokes the CPLs device info property sheet.
//
//  Parameters:
//      hwndParent
//          HWND to parent the property sheet.
//
//      pbtdi
//          A pointer to a BLUETOOTH_DEVICE_INFO structure of the device
//          to be displayed.
//
//  Return Values:
//      TRUE
//          The property page was successfully displayed.
//
//      FALSE
//          Failure. The property page was not displayed. Check GetLastError
//          for more details.
//
 
function BluetoothDisplayDeviceProperties(hwndParent: HWND; pbtdi: PBLUETOOTH_DEVICE_INFO): BOOL; stdcall;
{$EXTERNALSYM BluetoothDisplayDeviceProperties}
 
// ***************************************************************************
//
//  Radio Authentication
//
// ***************************************************************************
 
//
//  Description:
//      Sends an authentication request to a remote device.
//                                          
//      There are two modes of operation. "Wizard mode" and "Blind mode."
//
//      "Wizard mode" is invoked when the pszPasskey is NULL. This will cause
//      the "Bluetooth Connection Wizard" to be invoked. The user will be
//      prompted to enter a passkey during the wizard after which the
//      authentication request will be sent. The user will see the success
//      or failure of the authentication attempt. The user will also be
//      given the oppurtunity to try to fix a failed authentication.
//
//      "Blind mode" is invoked when the pszPasskey is non-NULL. This will
//      cause the computer to send a authentication request to the remote
//      device. No UI is ever displayed. The Bluetooth status code will be
//      mapped to a Win32 Error code.
//
//  Parameters:
//
//      hwndParent
//          The window to parent the authentication wizard. If NULL, the
//          wizard will be parented off the desktop.
//
//      hRadio
//          A valid local radio handle or NULL. If NULL, then all radios will
//          be tired. If any of the radios succeed, then the call will
//          succeed.
//
//      pbtdi
//          BLUETOOTH_DEVICE_INFO record of the device to be authenticated.
//
//      pszPasskey
//          PIN to be used to authenticate the device.  If NULL, then UI is
//          displayed and the user steps through the authentication process.
//          If not NULL, no UI is shown.  The passkey is NOT NULL terminated.
//
//      ulPasskeyLength
//          Length of szPassKey in bytes. The length must be less than or
//          equal to BLUETOOTH_MAX_PASSKEY_SIZE * sizeof(WCHAR).
//
//  Return Values:
//
//      ERROR_SUCCESS
//          Success.
//
//      ERROR_CANCELLED
//          User aborted the operation.
//
//      ERROR_INVALID_PARAMETER
//          The device structure in pbtdi is invalid.
//
//      ERROR_NO_MORE_ITEMS
//          The device in pbtdi is already been marked as authenticated.
//
//      other WIN32 error
//          Failure. Return value is the error code.
//
//      For "Blind mode," here is the current mapping of Bluetooth status
//      code to Win32 error codes:
//
//          { BTH_ERROR_SUCCESS,                ERROR_SUCCESS },
//          { BTH_ERROR_NO_CONNECTION,          ERROR_DEVICE_NOT_CONNECTED },
//          { BTH_ERROR_PAGE_TIMEOUT,           WAIT_TIMEOUT },
//          { BTH_ERROR_HARDWARE_FAILURE,       ERROR_GEN_FAILURE },
//          { BTH_ERROR_AUTHENTICATION_FAILURE, ERROR_NOT_AUTHENTICATED },
//          { BTH_ERROR_MEMORY_FULL,            ERROR_NOT_ENOUGH_MEMORY },
//          { BTH_ERROR_CONNECTION_TIMEOUT,     WAIT_TIMEOUT },
//          { BTH_ERROR_LMP_RESPONSE_TIMEOUT,   WAIT_TIMEOUT },
//          { BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS, ERROR_REQ_NOT_ACCEP },
//          { BTH_ERROR_PAIRING_NOT_ALLOWED,    ERROR_ACCESS_DENIED },
//          { BTH_ERROR_UNSPECIFIED_ERROR,      ERROR_NOT_READY },
//          { BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION, ERROR_VC_DISCONNECTED },
//
 
function BluetoothAuthenticateDevice(
    hwndParent
: HWND;
    hRadio
: THandle;
    pbtbi
: PBLUETOOTH_DEVICE_INFO;
    pszPasskey
: PWideChar;
    ulPasskeyLength
: ULONG): DWORD; stdcall;
{$EXTERNALSYM BluetoothAuthenticateDevice}
 
//
//  Description:
//      Allows the caller to prompt for multiple devices to be authenticated
//      within a single instance of the "Bluetooth Connection Wizard."
//
//  Parameters:
//
//      hwndParent
//          The window to parent the authentication wizard. If NULL, the
//          wizard will be parented off the desktop.
//
//      hRadio
//          A valid local radio handle or NULL. If NULL, then all radios will
//          be tired. If any of the radios succeed, then the call will
//          succeed.
//
//      cDevices
//          Number of devices in the rgbtdi array.
//
//      rgbtdi
//          An array BLUETOOTH_DEVICE_INFO records of the devices to be
//          authenticated.
//
//  Return Values:
//
//      ERROR_SUCCESS
//          Success. Check the fAuthenticate flag on each of the devices.
//
//      ERROR_CANCELLED
//          User aborted the operation. Check the fAuthenticate flags on
//          each device to determine if any of the devices were authenticated
//          before the user cancelled the operation.
//
//      ERROR_INVALID_PARAMETER
//          One of the items in the array of devices is invalid.
//
//      ERROR_NO_MORE_ITEMS
//          All the devices in the array of devices are already been marked as
//          being authenticated.
//
//      other WIN32 error
//          Failure. Return value is the error code.
//
 
function BluetoothAuthenticateMultipleDevices(
    hwndParent
: HWND;
    hRadio
: THandle;
    cDevices
: DWORD;
    pbtdi
: PBLUETOOTH_DEVICE_INFO): DWORD; stdcall;
{$EXTERNALSYM BluetoothAuthenticateMultipleDevices}
 
// ***************************************************************************
//
//  Bluetooth Services
//
// ***************************************************************************
 
const
  BLUETOOTH_SERVICE_DISABLE  
= $00;
 
{$EXTERNALSYM BLUETOOTH_SERVICE_DISABLE}
  BLUETOOTH_SERVICE_ENABLE  
= $01;
 
{$EXTERNALSYM BLUETOOTH_SERVICE_ENABLE}
  BLUETOOTH_SERVICE_MASK    
= BLUETOOTH_SERVICE_ENABLE or BLUETOOTH_SERVICE_DISABLE;
 
{$EXTERNALSYM BLUETOOTH_SERVICE_MASK}
 
//
//  Description:
//      Enables/disables the services for a particular device.
//
//      The system maintains a mapping of service guids to supported drivers for
//      Bluetooth-enabled devices. Enabling a service installs the corresponding
//      device driver. Disabling a service removes the corresponding device driver.
//
//      If a non-supported service is enabled, a driver will not be installed.
//
//  Parameters
//      hRadio
//          Handle of the local Bluetooth radio device.
//
//      pbtdi
//          Pointer to a BLUETOOTH_DEVICE_INFO record.
//
//      pGuidService
//          The service GUID on the remote device.
//
//      dwServiceFlags
//          Flags to adjust the service.
//              BLUETOOTH_SERVICE_DISABLE   -   disable the service
//              BLUETOOTH_SERVICE_ENABLE    -   enables the service
//
//  Return Values:
//      ERROR_SUCCESS
//          The call was successful.
//
//      ERROR_INVALID_PARAMETER
//          dwServiceFlags are invalid.
//
//      ERROR_SERVICE_DOES_NOT_EXIST
//          The GUID in pGuidService is not supported.
//
//      other WIN32 error
//          The call failed.
//
 
function BluetoothSetServiceState(
    hRadio
: THandle;
    pbtdi
: PBLUETOOTH_DEVICE_INFO;
   
const pGuidService: TGUID;
    dwServiceFlags
: DWORD): DWORD; stdcall;
{$EXTERNALSYM BluetoothSetServiceState}
 
//
//  Description:
//      Enumerates the services guids enabled on a particular device. If hRadio
//      is NULL, all device will be searched for the device and all the services
//      enabled will be returned.
//
//  Parameters:
//      hRadio
//          Handle of the local Bluetooth radio device. If NULL, it will search
//          all the radios for the address in the pbtdi.
//
//      pbtdi
//          Pointer to a BLUETOOTH_DEVICE_INFO record.
//
//      pcService
//          On input, the number of records pointed to by pGuidServices.
//          On output, the number of valid records return in pGuidServices.
//
//      pGuidServices
//          Pointer to memory that is at least *pcService in length.
//
//  Return Values:
//      ERROR_SUCCESS
//          The call succeeded. pGuidServices is valid.
//
//      ERROR_MORE_DATA
//          The call succeeded. pGuidService contains an incomplete list of
//          enabled service GUIDs.
//
//      other WIN32 errors
//          The call failed.
//
 
function BluetoothEnumerateInstalledServices(
    hRadio
: THandle;
    pbtdi
: PBLUETOOTH_DEVICE_INFO;
   
var pcServices: DWORD;
    pGuidServices
: PGUID): DWORD; stdcall;
{$EXTERNALSYM BluetoothEnumerateInstalledServices}
 
//
//  Description:
//      Change the discovery state of the local radio(s).
//      If hRadio is NULL, all the radios will be set.
//
//      Use BluetoothIsDiscoverable() to determine the radios current state.
//
//      The system ensures that a discoverable system is connectable, thus
//      the radio must allow incoming connections (see
//      BluetoothEnableIncomingConnections) prior to making a radio
//      discoverable. Failure to do so will result in this call failing
//      (returns FALSE).
//
//  Parameters:
//      hRadio
//          If not NULL, changes the state of a specific radio.
//          If NULL, the API will interate through all the radios.
//
//      fEnabled
//          If FALSE, discovery will be disabled.
//
//  Return Values
//      TRUE
//          State was successfully changed. If the caller specified NULL for
//          hRadio, at least of the radios accepted the state change.
//
//      FALSE
//          State was not changed. If the caller specified NULL for hRadio, all
//          of the radios did not accept the state change.
//
 
function BluetoothEnableDiscovery(hRadio: THandle; fEnabled: BOOL): BOOL; stdcall;
{$EXTERNALSYM BluetoothEnableDiscovery}
 
//
//  Description:
//      Determines if the Bluetooth radios are discoverable. If there are
//      multiple radios, the first one to say it is discoverable will cause
//      this function to return TRUE.
//
//  Parameters:
//      hRadio
//          Handle of the radio to check. If NULL, it will check all local
//          radios.
//
//  Return Values:
//      TRUE
//          A least one radio is discoverable.
//
//      FALSE
//          No radios are discoverable.
//
 
function BluetoothIsDiscoverable(hRadio: THandle): BOOL; stdcall;
{$EXTERNALSYM BluetoothIsDiscoverable}
 
//
//  Description:
//      Enables/disables the state of a radio to accept incoming connections.
//      If hRadio is NULL, all the radios will be set.
//
//      Use BluetoothIsConnectable() to determine the radios current state.
//
//      The system enforces that a radio that is not connectable is not
//      discoverable too. The radio must be made non-discoverable (see
//      BluetoothEnableDiscovery) prior to making a radio non-connectionable.
//      Failure to do so will result in this call failing (returns FALSE).
//
//  Parameters:
//      hRadio
//          If not NULL, changes the state of a specific radio.
//          If NULL, the API will interate through all the radios.
//
//      fEnabled
//          If FALSE, incoming connection will be disabled.
//
//  Return Values
//      TRUE
//          State was successfully changed. If the caller specified NULL for
//          hRadio, at least of the radios accepted the state change.
//
//      FALSE
//          State was not changed. If the caller specified NULL for hRadio, all
//          of the radios did not accept the state change.
//
 
function BluetoothEnableIncomingConnections(hRadio: THandle; fEnabled: BOOL): BOOL; stdcall;
{$EXTERNALSYM BluetoothEnableIncomingConnections}
 
//
//  Description:
//      Determines if the Bluetooth radios are connectable. If there are
//      multiple radios, the first one to say it is connectable will cause
//      this function to return TRUE.
//
//  Parameters:
//      hRadio
//          Handle of the radio to check. If NULL, it will check all local
//          radios.
//
//  Return Values:
//      TRUE
//          A least one radio is allowing incoming connections.
//
//      FALSE
//          No radios are allowing incoming connections.
//
 
function BluetoothIsConnectable(hRadio: THandle): BOOL; stdcall;
{$EXTERNALSYM BluetoothIsConnectable}
 
// ***************************************************************************
//
//  Authentication Registration
//
// ***************************************************************************
 
type
  HBLUETOOTH_AUTHENTICATION_REGISTRATION
= THandle;
 
{$EXTERNALSYM HBLUETOOTH_AUTHENTICATION_REGISTRATION}
 
  PFN_AUTHENTICATION_CALLBACK
= function(pvParam: Pointer; pDevice: PBLUETOOTH_DEVICE_INFO): BOOL; stdcall;
 
{$EXTERNALSYM PFN_AUTHENTICATION_CALLBACK}
 
//
//  Description:
//      Registers a callback function to be called when a particular device
//      requests authentication. The request is sent to the last application
//      that requested authentication for a particular device.
//
//  Parameters:
//      pbtdi
//          A pointer to a BLUETOOTH_DEVICE_INFO structure. The Bluetooth
//          address will be used for comparision.
//
//      phRegHandle
//          A pointer to where the registration HANDLE value will be
//          stored. Call BluetoothUnregisterAuthentication() to close
//          the handle.
//
//      pfnCallback
//          The function that will be called when the authentication event
//          occurs. This function should match PFN_AUTHENTICATION_CALLBACK's
//          prototype.
//
//      pvParam
//          Optional parameter to be past through to the callback function.
//          This can be anything the application was to define.
//
//  Return Values:
//      ERROR_SUCCESS
//          Success. A valid registration handle was returned.
//
//      ERROR_OUTOFMEMORY
//          Out of memory.
//
//      other Win32 error.
//          Failure. The registration handle is invalid.
//
 
function BluetoothRegisterForAuthentication(
    pbtdi
: PBLUETOOTH_DEVICE_INFO;
   
var phRegHandle: HBLUETOOTH_AUTHENTICATION_REGISTRATION;
    pfnCallback
: PFN_AUTHENTICATION_CALLBACK;
    pvParam
: Pointer): DWORD; stdcall;
{$EXTERNALSYM BluetoothRegisterForAuthentication}
 
//
//  Description:
//      Unregisters an authentication callback and closes the handle. See
//      BluetoothRegisterForAuthentication() for more information about
//      authentication registration.
//
//  Parameters:
//      hRegHandle
//          Handle returned by BluetoothRegisterForAuthentication().
//
//  Return Value:
//      TRUE
//          The handle was successfully closed.
//
//      FALSE
//          The handle was not successfully closed. Check GetLastError for
//          more details.
//
//          ERROR_INVALID_HANDLE
//              The handle is NULL.
//
//          other Win32 errors.
//
 
function BluetoothUnregisterAuthentication(hRegHandle: HBLUETOOTH_AUTHENTICATION_REGISTRATION): BOOL; stdcall;
{$EXTERNALSYM BluetoothUnregisterAuthentication}
 
//
//  Description:
//      This function should be called after receiving an authentication request
//      to send the passkey response.
//
//  Parameters:
//
//      hRadio
//          Optional handle to the local radio. If NULL, the function will try
//          each radio until one succeeds.
//
//      pbtdi
//          A pointer to a BLUETOOTH_DEVICE_INFO structure describing the device
//          being authenticated. This can be the same structure passed to the
//          callback function.
//
//      pszPasskey
//          A pointer to UNICODE zero-terminated string of the passkey response
//          that should be sent back to the authenticating device.
//
//  Return Values:
//      ERROR_SUCESS
//          The device accepted the passkey response. The device is authenticated.
//
//      ERROR_CANCELED
//          The device denied the passkey reponse. This also will returned if there
//          is a communications problem with the local radio.
//
//      E_FAIL
//          The device returned a failure code during authentication.
//
//      other Win32 error codes
//
 
function BluetoothSendAuthenticationResponse(
    hRadio
: THandle;
    pbtdi
: PBLUETOOTH_DEVICE_INFO;
    pszPasskey
: LPWSTR): DWORD; stdcall;
{$EXTERNALSYM BluetoothSendAuthenticationResponse}
 
// ***************************************************************************
//
//  SDP Parsing Functions
//
// ***************************************************************************
 
type
 
TSpdElementDataString = record
   
// raw string buffer, may not be encoded as ANSI, use
   
// BluetoothSdpGetString to convert the value if it is described
   
// by the base language attribute ID list
    value
: PBYTE;
   
// raw length of the string, may not be NULL terminuated
    length
: ULONG;
 
end;
 
 
TSpdElementDataUrl = record
    value
: PBYTE;
    length
: ULONG;
 
end;
 
 
// type == SDP_TYPE_SEQUENCE
 
TSpdElementDataSequence = record
   
// raw sequence, starts at sequence element header
    value
: PBYTE;
   
// raw sequence length
    length
: ULONG;
 
end;
 
 
// type == SDP_TYPE_ALTERNATIVE
 
TSpdElementDataAlternative = record
   
// raw alternative, starts at alternative element header
    value
: PBYTE;
   
// raw alternative length
    length
: ULONG;
 
end;
 
  _SDP_ELEMENT_DATA
= record
   
//
   
// Enumeration of SDP element types.  Generic element types will have a
   
// specificType value other then SDP_ST_NONE.  The generic types are:
   
// o SDP_TYPE_UINT
   
// o SDP_TYPE_INT
   
// o SDP_TYPE_UUID
   
//
    type_
: SDP_TYPE;
 
   
//
   
// Specific types for the generic SDP element types.
   
//
    specificType
: SDP_SPECIFICTYPE;
 
   
//
   
// Union of all possible data types.  type and specificType will indicate
   
// which field is valid.  For types which do not have a valid specificType,
   
// specific type will be SDP_ST_NONE.
   
//
   
case Integer of
       
// type == SDP_TYPE_INT
       
0: (int128: SDP_LARGE_INTEGER_16);        // specificType == SDP_ST_INT128
       
1: (int64: LONGLONG);                     // specificType == SDP_ST_INT64
       
2: (int32: Integer);                         // specificType == SDP_ST_INT32
       
3: (int16: SHORT);                        // specificType == SDP_ST_INT16
       
4: (int8: CHAR);                          // specificType == SDP_ST_INT8
 
       
// type == SDP_TYPE_UINT
       
5: (uint128: SDP_ULARGE_INTEGER_16);      // specificType == SDP_ST_UINT128
       
6: (uint64: Int64);                   // specificType == SDP_ST_UINT64
       
7: (uint32: ULONG);                       // specificType == SDP_ST_UINT32
       
8: (uint16: Word);                      // specificType == SDP_ST_UINT16
       
9: (uint8: UCHAR);                        // specificType == SDP_ST_UINT8
 
       
// type == SDP_TYPE_BOOLEAN
       
10: (booleanVal: UCHAR);
 
       
// type == SDP_TYPE_UUID
       
11: (uuid128: TGUID);                       // specificType == SDP_ST_UUID128
       
12: (uuid32: ULONG);                       // specificType == SDP_ST_UUID32
       
13: (uuid16: Word);                      // specificType == SDP_ST_UUID32
 
       
// type == SDP_TYPE_STRING
       
14: (string_: TSpdElementDataString);
       
// type == SDP_TYPE_URL
       
15: (url: TSpdElementDataUrl);
 
       
// type == SDP_TYPE_SEQUENCE
       
16: (sequence: TSpdElementDataSequence);
 
       
// type == SDP_TYPE_ALTERNATIVE
       
17: (alternative: TSpdElementDataAlternative);
 
end;
 
{$EXTERNALSYM _SDP_ELEMENT_DATA}
  SDP_ELEMENT_DATA
= _SDP_ELEMENT_DATA;
 
{$EXTERNALSYM SDP_ELEMENT_DATA}
  PSDP_ELEMENT_DATA
= ^SDP_ELEMENT_DATA;
 
{$EXTERNALSYM PSDP_ELEMENT_DATA}
 
TSdpElementData = SDP_ELEMENT_DATA;
 
PSdpElementData = PSDP_ELEMENT_DATA;  
 
//
// Description:
//      Retrieves and parses the element found at pSdpStream
//
// Parameters:
//      IN pSdpStream
//          pointer to valid SDP stream
//
//      IN cbSdpStreamLength
//          length of pSdpStream in bytes
//
//      OUT pData
//          pointer to be filled in with the data of the SDP element at the
//          beginning of pSdpStream
//
// Return Values:
//      ERROR_INVALID_PARAMETER
//          one of required parameters is NULL or the pSdpStream is invalid
//
//      ERROR_SUCCESS
//          the sdp element was parsed correctly
//
 
function BluetoothSdpGetElementData(
    pSdpStream
: PBYTE;
    cbSdpStreamLength
: ULONG;
    pData
: PSDP_ELEMENT_DATA): DWORD; stdcall;
{$EXTERNALSYM BluetoothSdpGetElementData}
 
type
  HBLUETOOTH_CONTAINER_ELEMENT
= THandle;
 
{$EXTERNALSYM HBLUETOOTH_CONTAINER_ELEMENT}
 
//
// Description:
//      Iterates over a container stream, returning each elemetn contained with
//      in the container element at the beginning of pContainerStream
//
// Parameters:
//      IN pContainerStream
//          pointer to valid SDP stream whose first element is either a sequence
//          or alternative
//
//      IN cbContainerlength
//          length in bytes of pContainerStream
//
//      IN OUT pElement
//          Value used to keep track of location within the stream.  The first
//          time this function is called for a particular container, *pElement
//          should equal NULL.  Upon subsequent calls, the value should be
//          unmodified.
//
//      OUT pData
//          pointer to be filled in with the data of the SDP element at the
//          current element of pContainerStream
//
//  Return Values:
//      ERROR_SUCCESS
//          The call succeeded, pData contains the data
//
//      ERROR_NO_MORE_ITEMS
//          There are no more items in the list, the caller should cease calling
//          BluetoothSdpGetContainerElementData for this container.
//
//      ERROR_INVALID_PARAMETER
//          A required pointer is NULL or the container is not a valid SDP
//          stream
//
// Usage example:
//
// HBLUETOOTH_CONTAINER_ELEMENT element;
// SDP_ELEMENT_DATA data;
// ULONG result;
//
// element = NULL;
//
// while (TRUE) {
//      result = BluetoothSdpGetContainerElementData(
//          pContainer, ulContainerLength, &element, &data);
//
//      if (result == ERROR_NO_MORE_ITEMS) {
//          // We are done
//          break;
//      }
//      else if (result != ERROR_SUCCESS) {
//          // error
//      }
//
//      // do something with data ...
// }
//
//
 
function BluetoothSdpGetContainerElementData(
    pContainerStream
: PBYTE;
    cbContainerLength
: ULONG;
   
var pElement: HBLUETOOTH_CONTAINER_ELEMENT;
    pData
: PSDP_ELEMENT_DATA): DWORD; stdcall;
{$EXTERNALSYM BluetoothSdpGetContainerElementData}
 
//
// Description:
//      Retrieves the attribute value for the given attribute ID.  pRecordStream
//      must be an SDP stream that is formatted as an SDP record, a SEQUENCE
//      containing UINT16 + element pairs.
//
// Parameters:
//      IN pRecordStream
//          pointer to a valid SDP stream which is formatted as a singl SDP
//          record
//
//      IN cbRecordlnegh
//          length of pRecordStream in bytes
//
//      IN usAttributeId
//          the attribute ID to search for.  see bthdef.h for SDP_ATTRIB_Xxx
//          values.
//
//      OUT pAttributeData
//          pointer that will contain the attribute ID's value
//
// Return Values:
//      ERRROR_SUCCESS
//          Call succeeded, pAttributeData contains the attribute value
//
//      ERROR_INVALID_PARAMETER
//          One of the required pointers was NULL, pRecordStream was not a valid
//          SDP stream, or pRecordStream was not a properly formatted SDP record
//
//      ERROR_FILE_NOT_FOUND
//          usAttributeId was not found in the record
//
// Usage:
//
// ULONG result;
// SDP_DATA_ELEMENT data;
//
// result = BluetoothSdpGetAttributeValue(
//      pRecordStream, cbRecordLength, SDP_ATTRIB_RECORD_HANDLE, &data);
// if (result == ERROR_SUCCESS) {
//      printf("record handle is 0x%x\n", data.data.uint32);
// }
//
 
function BluetoothSdpGetAttributeValue(
    pRecordStream
: PBYTE;
    cbRecordLength
: ULONG;
    usAttributeId
: Word;
    pAttributeData
: PSDP_ELEMENT_DATA): DWORD; stdcall;
{$EXTERNALSYM BluetoothSdpGetAttributeValue}
 
//
// These three fields correspond one to one with the triplets defined in the
// SDP specification for the language base attribute ID list.
//
 
type
  _SDP_STRING_TYPE_DATA
= record
   
//
   
// How the string is encoded according to ISO 639:1988 (E/F): "Code
   
// for the representation of names of languages".
   
//
    encoding
: Word;
 
   
//
   
// MIBE number from IANA database
   
//
    mibeNum
: Word;
 
   
//
   
// The base attribute where the string is to be found in the record
   
//
    attributeId
: Word;
 
end;
 
{$EXTERNALSYM _SDP_STRING_TYPE_DATA}
  SDP_STRING_TYPE_DATA
= _SDP_STRING_TYPE_DATA;
 
{$EXTERNALSYM SDP_STRING_TYPE_DATA}
  PSDP_STRING_TYPE_DATA
= ^SDP_STRING_TYPE_DATA;
 
{$EXTERNALSYM PSDP_STRING_TYPE_DATA}
 
TSdpStringTypeData = SDP_STRING_TYPE_DATA;
 
PSdpStringTypeData = PSDP_STRING_TYPE_DATA;  
 
//
// Description:
//      Converts a raw string embedded in the SDP record into a UNICODE string
//
// Parameters:
//      IN pRecordStream
//          a valid SDP stream which is formatted as an SDP record
//
//      IN cbRecordLength
//          length of pRecordStream in bytes
//
//      IN pStringData
//          if NULL, then the calling thread's locale will be used to search
//          for a matching string in the SDP record.  If not NUL, the mibeNum
//          and attributeId will be used to find the string to convert.
//
//      IN usStringOffset
//          the SDP string type offset to convert.  usStringOffset is added to
//          the base attribute id of the string.   SDP specification defined
//          offsets are: STRING_NAME_OFFSET, STRING_DESCRIPTION_OFFSET, and
//          STRING_PROVIDER_NAME_OFFSET (found in bthdef.h).
//
//      OUT pszString
//          if NULL, pcchStringLength will be filled in with the required number
//          of characters (not bytes) to retrieve the converted string.
//
//      IN OUT pcchStringLength
//          Upon input, if pszString is not NULL, will contain the length of
//          pszString in characters.  Upon output, it will contain either the
//          number of required characters including NULL if an error is returned
//          or the number of characters written to pszString (including NULL).
//
//  Return Values:
//      ERROR_SUCCES
//          Call was successful and pszString contains the converted string
//
//      ERROR_MORE_DATA
//          pszString was NULL or too small to contain the converted string,
//          pccxhStringLength contains the required length in characters
//
//      ERROR_INVALID_DATA
//          Could not perform the conversion
//
//      ERROR_NO_SYSTEM_RESOURCES
//          Could not allocate memory internally to perform the conversion
//
//      ERROR_INVALID_PARAMETER
//          One of the rquired pointers was NULL, pRecordStream was not a valid
//          SDP stream, pRecordStream was not a properly formatted record, or
//          the desired attribute + offset was not a string.
//
//      Other HRESULTs returned by COM
//
 
function BluetoothSdpGetString(
    pRecordStream
: PBYTE;
    cbRecordLength
: ULONG;
    pStringData
: PSDP_STRING_TYPE_DATA;
    usStringOffset
: Word;
    pszString
: PWideChar;
    pcchStringLength
: PULONG): DWORD; stdcall;
{$EXTERNALSYM BluetoothSdpGetString}
 
// ***************************************************************************
//
//  Raw Attribute  Enumeration
//
// ***************************************************************************
 
type
  PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK
= function(
    uAttribId
: ULONG;
    pValueStream
: PBYTE;
    cbStreamSize
: ULONG;
    pvParam
: Pointer): BOOL; stdcall;
 
{$EXTERNALSYM PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK}
 
//
//  Description:
//      Enumerates through the SDP record stream calling the Callback function
//      for each attribute in the record. If the Callback function returns
//      FALSE, the enumeration is stopped.
//
//  Return Values:
//      TRUE
//          Success! Something was enumerated.
//
//      FALSE
//          Failure. GetLastError() could be one of the following:
//
//          ERROR_INVALID_PARAMETER
//              pSDPStream or pfnCallback is NULL.
//
//          ERROR_INVALID_DATA
//              The SDP stream is corrupt.
//
//          other Win32 errors.
//
 
function BluetoothSdpEnumAttributes(
    pSDPStream
: PBYTE;
    cbStreamSize
: ULONG;
    pfnCallback
: PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK;
    pvParam
: Pointer): BOOL; stdcall;
{$EXTERNALSYM BluetoothSdpEnumAttributes}
 
// (rom) MACRO
function BluetoothEnumAttributes(
    pSDPStream
: PBYTE;
    cbStreamSize
: ULONG;
    pfnCallback
: PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK;
    pvParam
: Pointer): BOOL;
{$EXTERNALSYM BluetoothEnumAttributes}
 
implementation
 
const
  btapi
= 'irprops.cpl';
 
// (rom) MACRO implementation
function BluetoothEnumAttributes(pSDPStream: PBYTE; cbStreamSize: ULONG;
  pfnCallback
: PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK; pvParam: Pointer): BOOL;
begin
 
Result := BluetoothSdpEnumAttributes(pSDPStream, cbStreamSize, pfnCallback, pvParam);
end;
 
function BluetoothFindFirstRadio; external btapi name 'BluetoothFindFirstRadio';
function BluetoothFindNextRadio; external btapi name 'BluetoothFindNextRadio';
function BluetoothFindRadioClose; external btapi name 'BluetoothFindRadioClose';
function BluetoothGetRadioInfo; external btapi name 'BluetoothGetRadioInfo';
function BluetoothFindFirstDevice; external btapi name 'BluetoothFindFirstDevice';
function BluetoothFindNextDevice; external btapi name 'BluetoothFindNextDevice';
function BluetoothFindDeviceClose; external btapi name 'BluetoothFindDeviceClose';
function BluetoothGetDeviceInfo; external btapi name 'BluetoothGetDeviceInfo';
function BluetoothUpdateDeviceRecord; external btapi name 'BluetoothUpdateDeviceRecord';
function BluetoothRemoveDevice; external btapi name 'BluetoothRemoveDevice';
function BluetoothSelectDevices; external btapi name 'BluetoothSelectDevices';
function BluetoothSelectDevicesFree; external btapi name 'BluetoothSelectDevicesFree';
function BluetoothDisplayDeviceProperties; external btapi name 'BluetoothDisplayDeviceProperties';
function BluetoothAuthenticateDevice; external btapi name 'BluetoothAuthenticateDevice';
function BluetoothAuthenticateMultipleDevices; external btapi name 'BluetoothAuthenticateMultipleDevices';
function BluetoothSetServiceState; external btapi name 'BluetoothSetServiceState';
function BluetoothEnumerateInstalledServices; external btapi name 'BluetoothEnumerateInstalledServices';
function BluetoothEnableDiscovery; external btapi name 'BluetoothEnableDiscovery';
function BluetoothIsDiscoverable; external btapi name 'BluetoothIsDiscoverable';
function BluetoothEnableIncomingConnections; external btapi name 'BluetoothEnableIncomingConnections';
function BluetoothIsConnectable; external btapi name 'BluetoothIsConnectable';
function BluetoothRegisterForAuthentication; external btapi name 'BluetoothRegisterForAuthentication';
function BluetoothUnregisterAuthentication; external btapi name 'BluetoothUnregisterAuthentication';
function BluetoothSendAuthenticationResponse; external btapi name 'BluetoothSendAuthenticationResponse';
function BluetoothSdpGetElementData; external btapi name 'BluetoothSdpGetElementData';
function BluetoothSdpGetContainerElementData; external btapi name 'BluetoothSdpGetContainerElementData';
function BluetoothSdpGetAttributeValue; external btapi name 'BluetoothSdpGetAttributeValue';
function BluetoothSdpGetString; external btapi name 'BluetoothSdpGetString';
function BluetoothSdpEnumAttributes; external btapi name 'BluetoothSdpEnumAttributes';
 
end.
 
 
 
{
 
Copyright (C) 2006 Mike B. Petrichenko
  pmb_stv@mail
.ru
  mobileservicesoft@yandex
.ru
  ICQ
: 190812766
 
Phone: +7 (928) 324-58-24
         
+7 (928) 819-46-40
 
 
All Rights Reserved.
 
 
Only for non commercial purpose.
}
unit
BTDevice;
 
interface
 
uses
 
BTRadio, BluetoothAPI, Windows;
 
type
 
TBTDeviceSearchFlag = (sfReturnAuthenticated, sfReturnRemembered,
                         sfReturnUnknown
, sfReturnConnected);
 
TBTDeviceSearchFlags = set of TBTDeviceSearchFlag;
 
 
TBTDeviceSelectFlag = (dsForceAuthentication, dsShowAuthenticated,
                         dsShowRemembered
, dsShowUnknown, dsAddNewDeviceWizard,
                         dsSkipServicesPage
);
 
TBTDeviceSelectFlags = set of TBTDeviceSelectFlag;
 
 
TBTAuthenticateEvent = procedure (Sender: TObject; var Pwd: string);
 
 
TBTDevice = class
 
private
   
FAddress: BTH_ADDR;
   
FAuReg: HBLUETOOTH_AUTHENTICATION_REGISTRATION;
   
FBTRadio: TBTRadio;
   
FOnAuthenticate: TBTAuthenticateEvent;
 
   
function GetAuthenticated: boolean;
   
function GetClassOfDevice: cardinal;
   
function GetConnected: boolean;
   
function GetDeviceInfo: BLUETOOTH_DEVICE_INFO;
   
function GetLastSeen: TDateTime;
   
function GetLastUsed: TDateTime;
   
function GetName: string;
   
function GetRemembered: boolean;
 
    procedure
SetOnAuthenticate(const Value: TBTAuthenticateEvent);
 
    procedure
DoAuthenticate;
 
 
protected
    property
DeviceInfo: BLUETOOTH_DEVICE_INFO read GetDeviceInfo;
 
 
public
   
constructor Create(const Addr: BTH_ADDR; const ABTRadio: TBTRadio);
    destructor
Destroy; override;
 
    procedure
Authenticate(const Pwd: string);
    procedure
DisplayProperties;
    procedure
Remove;
    procedure
Select(const FLags: TBTDeviceSelectFlags);
    procedure
Update(const NewName: string);
 
    property
Address: BTH_ADDR read FAddress;
    property
Authenticated: boolean read GetAuthenticated;
    property
BTRadio: TBTRadio read FBTRadio;
    property
ClassofDevice: cardinal read GetClassOfDevice;
    property
Connected: boolean read GetConnected;
    property
LastSeen: TDateTime read GetLastSeen;
    property
LastUsed: TDateTime read GetLastUsed;
    property
Name: string read GetName;
    property
Remembered: boolean read GetRemembered;
 
    property
OnAuthenticate: TBTAuthenticateEvent read FOnAuthenticate write SetOnAuthenticate;
 
end;
 
function BTGetDeviceByAddr(const Addr: BTH_ADDR; const ABTRadio: TBTRadio): TBTDevice;
 
procedure
BTEnumDevices(const BTRadio: TBTRadio; const SearchFlags: TBTDeviceSearchFlags; var Devices: TBTAddrArray);
 
implementation
 
uses
 
BTExceptions, BTStrings, SysUtils;
 
function BTAuCallBack(pvParam: Pointer; pDevice: PBLUETOOTH_DEVICE_INFO): BOOL; stdcall;
begin
 
TBTDevice(pvParam).DoAuthenticate;
 
Result := true;
end;
 
function BTGetDeviceByAddr(const Addr: BTH_ADDR; const ABTRadio: TBTRadio): TBTDevice;
begin
   
if (not Assigned(ABTRadio)) then raise BTException.Create(STR_ERROR_INVALID_PARAMETER);
 
   
Result := TBTDevice.Create(Addr, ABTRadio);
end;
 
procedure
BTEnumDevices(const BTRadio: TBTRadio; const SearchFlags: TBTDeviceSearchFlags; var Devices: TBTAddrArray);
var
  hFind
: HBLUETOOTH_DEVICE_FIND;
 
SearchParams: BLUETOOTH_DEVICE_SEARCH_PARAMS;
 
SearchParamsSize: dword;
 
DeviceInfo: BLUETOOTH_DEVICE_INFO;
 
DeviceInfoSize: dword;
 
Ndx: word;
begin
 
if (not Assigned(BTRadio)) then raise BTException.Create(STR_ERROR_INVALID_PARAMETER);
 
 
Ndx := 0;
 
 
SearchParamsSize := SizeOf(BLUETOOTH_DEVICE_SEARCH_PARAMS);
 
FillChar(SearchParams, SearchParamsSize, 0);
 
with SearchParams do begin
    dwSize
:= SearchParamsSize;
    hRadio
:= BTRadio.Handle;
    fReturnAuthenticated
:= (sfReturnAuthenticated in SearchFlags);
    fReturnRemembered
:= (sfReturnRemembered in SearchFlags);
    fReturnUnknown
:= (sfReturnUnknown in SearchFlags);
    fReturnConnected
:= (sfReturnConnected in SearchFlags);
 
end;
 
 
DeviceInfoSize := SizeOf(BLUETOOTH_DEVICE_INFO);
 
FillChar(DeviceInfo, DeviceInfoSize, 0);
 
DeviceInfo.dwSize := DeviceInfoSize;
 
  hFind
:=  BluetoothFindFirstDevice(SearchParams, DeviceInfo);
 
if (hFind <> 0) then begin
    repeat
     
Inc(Ndx);
     
SetLength(Devices, Ndx);
     
Devices[Ndx - 1] := DeviceInfo.Address.ullLong;
 
     
FillChar(DeviceInfo, DeviceInfoSize, 0);
     
DeviceInfo.dwSize := DeviceInfoSize;
   
until (not BluetoothFindNextDevice(hFind, DeviceInfo));
 
   
BluetoothFindDeviceClose(hFind);
 
end;
end;
 
function TBTDevice.GetAuthenticated: boolean;
begin
 
Result := boolean(GetDeviceInfo.fAuthenticated);
end;
 
function TBTDevice.GetClassOfDevice: cardinal;
begin
 
Result := GetDeviceInfo.ulClassofDevice;
end;
 
function TBTDevice.GetConnected: boolean;
begin
 
Result := boolean(GetDeviceInfo.fConnected);
end;
 
function TBTDevice.GetDeviceInfo: BLUETOOTH_DEVICE_INFO;
var
 
DeviceInfoSize: dword;
 
Res: dword;
begin
 
DeviceInfoSize := SizeOf(BLUETOOTH_DEVICE_INFO);
 
 
FillChar(Result, DeviceInfoSize, 0);
 
with Result do begin
    dwSize
:= DeviceInfoSize;
   
Address.ullLong := FAddress;
 
end;
 
 
Res := BluetoothGetDeviceInfo(FBTRadio.Handle, Result);
 
 
if (Res <> ERROR_SUCCESS) then
   
case Res of
      ERROR_REVISION_MISMATCH
: raise BTException.Create(STR_ERROR_REVISION_MISMATCH_DEV);
      ERROR_INVALID_PARAMETER
: raise BTException.Create(STR_ERROR_INVALID_PARAMETER_DEV);
   
else
     
RaiseLastOSError;
   
end;
end;
 
function TBTDevice.GetLastSeen: TDateTime;
begin
 
Result := SystemTimeToDateTime(GetDeviceInfo.stLastSeen);
end;
 
function TBTDevice.GetLastUsed: TDateTime;
begin
 
Result := SystemTimeToDateTime(GetDeviceInfo.stLastUsed);
end;
 
function TBTDevice.GetName: string;
begin
 
Result := string(widestring(GetDeviceInfo.szName));
end;
 
function TBTDevice.GetRemembered: boolean;
begin
 
Result := boolean(GetDeviceInfo.fRemembered);
end;
 
procedure
TBTDevice.SetOnAuthenticate(const Value: TBTAuthenticateEvent);
 
  procedure
Unreg;
 
begin
   
if (FAuReg <> 0) then
     
if (not BluetoothUnregisterAuthentication(FAuReg)) then
       
RaiseLastOsError;
   
FAuReg := 0;
   
FOnAuthenticate := nil;
 
end;
 
begin
 
if Assigned(Value) then begin
   
Unreg;
   
if (BluetoothRegisterForAuthentication(GetDeviceInfo, FAuReg, BTAuCallBack, Self) <> ERROR_SUCCESS) then begin
     
FAuReg := 0;
     
RaiseLastOSError;
   
end;
   
FOnAuthenticate := Value;
 
end else
   
Unreg;
end;
 
procedure
TBTDevice.DoAuthenticate;
var
 
Pwd: string;
begin
 
if Assigned(FOnAuthenticate) then begin
   
FOnAuthenticate(Self, Pwd);
   
BluetoothSendAuthenticationResponse(FBTRadio.Handle, GetDeviceInfo, pwidechar(widestring(Pwd)));
 
end;
end;
 
constructor TBTDevice.Create(const Addr: BTH_ADDR; const ABTRadio: TBTRadio);
begin
 
if (not Assigned(FBTRadio)) then raise BTException.Create(STR_ERROR_INVALID_PARAMETER);
 
 
FAddress := Addr;
 
FAuReg := 0;
 
FBTRadio := ABTRadio;
 
FOnAuthenticate := nil;
end;
 
destructor
TBTDevice.Destroy;
begin
 
if Assigned(FOnAuthenticate) then OnAuthenticate := nil;
 
  inherited
;
end;
 
procedure
TBTDevice.Authenticate(const Pwd: string);
var
 
Res: dword;
 
PPwd: pwidechar;
 
PPwdLength: dword;
begin
 
if (Pwd = '') then begin
   
PPwd := nil;
   
PPwdLength := 0;
 
end else begin
   
PPwd := pwidechar(widestring(Pwd));
   
PPwdLength := Length(WideString(Pwd));
 
end;
 
 
Res := BluetoothAuthenticateDevice(0, FBTRadio.Handle, GetDeviceInfo, PPwd, PPwdLength);
 
if (Res <> ERROR_SUCCESS) then RaiseLastOsError;
end;
 
procedure
TBTDevice.DisplayProperties;
begin
 
if (not BluetoothDisplayDeviceProperties(0, GetDeviceInfo)) then RaiseLastOsError;
end;
 
procedure
TBTDevice.Remove;
var
 
Addr: BLUETOOTH_ADDRESS;
begin
 
Addr.ullLong := FAddress;
 
if (BluetoothRemoveDevice(Addr) <> ERROR_SUCCESS) then RaiseLastOsError;
end;
 
procedure
TBTDevice.Select(const FLags: TBTDeviceSelectFlags);
var
 
SelectParams: BLUETOOTH_SELECT_DEVICE_PARAMS;
 
SelectParamsSize: dword;
 
Res: dword;
begin
 
SelectParamsSize := SizeOf(BLUETOOTH_SELECT_DEVICE_PARAMS);
 
FillChar(SelectParams, SelectParamsSize, 0);
 
with SelectParams do begin
    dwSize
:= SelectParamsSize;
    fForceAuthentication
:= (dsForceAuthentication in Flags);
    fShowAuthenticated
:= (dsShowAuthenticated in Flags);
    fShowRemembered
:= (dsShowRemembered in Flags);
    fShowUnknown
:= (dsShowUnknown in Flags);
    fAddNewDeviceWizard
:= (dsAddNewDeviceWizard in Flags);
    fSkipServicesPage
:= (dsSkipServicesPage in Flags);
 
end;
 
 
if BluetoothSelectDevices(@SelectParams) then begin
   
FAddress := BLUETOOTH_DEVICE_INFO(SelectParams.pDevices).Address.ullLong;
   
BluetoothSelectDevicesFree(@SelectParams);
 
end else begin
   
Res := GetLastError;
   
if (Res <> ERROR_CANCELLED) then
     
case Res of
        ERROR_INVALID_PARAMETER
: raise BTException.Create(STR_ERROR_INVALID_PARAMETER_SEL);
        ERROR_REVISION_MISMATCH
: raise BTException.Create(STR_ERROR_REVISION_MISMATCH_SEL);
     
else
       
RaiseLastOSError;
     
end;
 
end;
end;
 
procedure
TBTDevice.Update(const NewName: string);
var
 
DeviceInfo: BLUETOOTH_DEVICE_INFO;
 
DeviceInfoSize: dword;
 
Res: dword;
begin
 
DeviceInfoSize := SizeOf(BLUETOOTH_DEVICE_INFO);
 
FillChar(DeviceInfo, DeviceInfoSize, 0);
 
with DeviceInfo do begin
    dwSize
:= DeviceInfoSize;
   
Address.ullLong := FAddress;
    lstrcpyw
(szName, pwidechar(widestring(NewName)));
 
end;
 
 
Res := BluetoothUpdateDeviceRecord(DeviceInfo);
 
if (Res <> ERROR_SUCCESS) then
   
case Res of
      ERROR_INVALID_PARAMETER
: raise BTException.Create(STR_ERROR_INVALID_PARAMETER_DEV);
      ERROR_REVISION_MISMATCH
: raise BTException.Create(STR_ERROR_REVISION_MISMATCH_DEV);
   
else
     
RaiseLastOsError;
   
end;
end;
 
end.
{
 
Copyright (C) 2006 Mike B. Petrichenko
  pmb_stv@mail
.ru
  mobileservicesoft@yandex
.ru
  ICQ
: 190812766
 
Phone: +7 (928) 324-58-24
         
+7 (928) 819-46-40
 
 
All Rights Reserved.
 
 
Only for non commercial purpose.
}
unit
BTExceptions;
 
interface
 
uses
 
SysUtils;
 
type
 
BTException = class(Exception);
 
implementation
 
end.
unit BthSdpDef;
 
interface
 
uses
 
Windows;
 
type
  SDP_LARGE_INTEGER_16
= record
   
LowPart: Int64;
   
HighPart: Int64;
 
end;
 
{$EXTERNALSYM SDP_LARGE_INTEGER_16}
  PSDP_LARGE_INTEGER_16
= ^SDP_LARGE_INTEGER_16;
 
{$EXTERNALSYM PSDP_LARGE_INTEGER_16}
  LPSDP_LARGE_INTEGER_16
= PSDP_LARGE_INTEGER_16;
 
{$EXTERNALSYM LPSDP_LARGE_INTEGER_16}
 
TSdpLargeInteger = SDP_LARGE_INTEGER_16;
 
PSdpLargeInteger = PSDP_LARGE_INTEGER_16;
 
  SDP_ULARGE_INTEGER_16
= record
   
LowPart: Int64;
   
HighPart: Int64;
 
end;
 
{$EXTERNALSYM SDP_ULARGE_INTEGER_16}
  PSDP_ULARGE_INTEGER_16
= ^SDP_ULARGE_INTEGER_16;
 
{$EXTERNALSYM PSDP_ULARGE_INTEGER_16}
  LPSDP_ULARGE_INTEGER_16
= PSDP_ULARGE_INTEGER_16;
 
{$EXTERNALSYM LPSDP_ULARGE_INTEGER_16}
  TSdpULargeInteger16
= SDP_ULARGE_INTEGER_16;
  PSdpULargeInteger16
= PSDP_ULARGE_INTEGER_16;
 
 
NodeContainerType = (NodeContainerTypeSequence, NodeContainerTypeAlternative);
 
TNodeContainerType = NodeContainerType;
 
  SDP_ERROR
= Word;
 
{$EXTERNALSYM SDP_ERROR}
  PSDP_ERROR
= ^SDP_ERROR;
 
{$EXTERNALSYM PSDP_ERROR}
 
TSdpError = SDP_ERROR;
 
PSdpError = PSDP_ERROR;
 
type
  SDP_TYPE
= DWORD;
 
{$EXTERNALSYM SDP_TYPE}
 
TSdpType = SDP_TYPE;
 
const
  SDP_TYPE_NIL
= $00;
 
{$EXTERNALSYM SDP_TYPE_NIL}
  SDP_TYPE_UINT
= $01;
 
{$EXTERNALSYM SDP_TYPE_UINT}
  SDP_TYPE_INT
= $02;
 
{$EXTERNALSYM SDP_TYPE_INT}
  SDP_TYPE_UUID
= $03;
 
{$EXTERNALSYM SDP_TYPE_UUID}
  SDP_TYPE_STRING
= $04;
 
{$EXTERNALSYM SDP_TYPE_STRING}
  SDP_TYPE_BOOLEAN
= $05;
 
{$EXTERNALSYM SDP_TYPE_BOOLEAN}
  SDP_TYPE_SEQUENCE
= $06;
 
{$EXTERNALSYM SDP_TYPE_SEQUENCE}
  SDP_TYPE_ALTERNATIVE
= $07;
 
{$EXTERNALSYM SDP_TYPE_ALTERNATIVE}
  SDP_TYPE_URL
= $08;
 
{$EXTERNALSYM SDP_TYPE_URL}
 
// 9 - 31 are reserved
  SDP_TYPE_CONTAINER
= $20;
 
{$EXTERNALSYM SDP_TYPE_CONTAINER}
 
// allow for a little easier type checking / sizing for integers and UUIDs
// ((SDP_ST_XXX & 0xF0) >> 4) == SDP_TYPE_XXX
// size of the data (in bytes) is encoded as ((SDP_ST_XXX & 0xF0) >> 8)
 
type
  SDP_SPECIFICTYPE
= DWORD;
 
{$EXTERNALSYM SDP_SPECIFICTYPE}
 
TSdpSpecificType = SDP_SPECIFICTYPE;
 
const
  SDP_ST_NONE
= $0000;
 
{$EXTERNALSYM SDP_ST_NONE}
 
  SDP_ST_UINT8
= $0010;
 
{$EXTERNALSYM SDP_ST_UINT8}
  SDP_ST_UINT16
= $0110;
 
{$EXTERNALSYM SDP_ST_UINT16}
  SDP_ST_UINT32
= $0210;
 
{$EXTERNALSYM SDP_ST_UINT32}
  SDP_ST_UINT64
= $0310;
 
{$EXTERNALSYM SDP_ST_UINT64}
  SDP_ST_UINT128
= $0410;
 
{$EXTERNALSYM SDP_ST_UINT128}
 
  SDP_ST_INT8
= $0020;
 
{$EXTERNALSYM SDP_ST_INT8}
  SDP_ST_INT16
= $0120;
 
{$EXTERNALSYM SDP_ST_INT16}
  SDP_ST_INT32
= $0220;
 
{$EXTERNALSYM SDP_ST_INT32}
  SDP_ST_INT64
= $0320;
 
{$EXTERNALSYM SDP_ST_INT64}
  SDP_ST_INT128
= $0420;
 
{$EXTERNALSYM SDP_ST_INT128}
 
  SDP_ST_UUID16
= $0130;
 
{$EXTERNALSYM SDP_ST_UUID16}
  SDP_ST_UUID32
= $0220;
 
{$EXTERNALSYM SDP_ST_UUID32}
  SDP_ST_UUID128
= $0430;
 
{$EXTERNALSYM SDP_ST_UUID128}
 
type
  _SdpAttributeRange
= record
    minAttribute
: Word;
    maxAttribute
: Word;
 
end;
 
{$EXTERNALSYM _SdpAttributeRange}
 
SdpAttributeRange = _SdpAttributeRange;
 
{$EXTERNALSYM SdpAttributeRange}
 
TSdpAttributeRange = SdpAttributeRange;
 
 
SdpQueryUuidUnion = record
   
case Integer of
     
0: (uuid128: TGUID);
     
1: (uuid32: ULONG);
     
2: (uuid16: Word);
 
end;
 
TSdpQueryUuidUnion = SdpQueryUuidUnion;
 
  _SdpQueryUuid
= record
    u
: SdpQueryUuidUnion;
    uuidType
: Word;
 
end;
 
{$EXTERNALSYM _SdpQueryUuid}
 
SdpQueryUuid = _SdpQueryUuid;
 
{$EXTERNALSYM SdpQueryUuid}
 
TSdpQueryUuid = SdpQueryUuid;
 
implementation
 
end.
 
{
 
Copyright (C) 2006 Mike B. Petrichenko
  pmb_stv@mail
.ru
  mobileservicesoft@yandex
.ru
  ICQ
: 190812766
 
Phone: +7 (928) 324-58-24
         
+7 (928) 819-46-40
 
 
All Rights Reserved.
 
 
Only for non commercial purpose.
}
unit
BTRadio;
 
interface
 
uses
 
Windows, BluetoothAPI;
 
type
 
TBTAddrArray = array of BTH_ADDR;
 
 
TBTRadio = class
 
private
   
FAddress: BTH_ADDR;
   
FClassOfDevice: cardinal;
   
FHandle: THandle;
   
FManufacturer: word;
   
FName: string;
   
FSubversion: word;
 
   
function GetConnectable: boolean;
   
function GetDiscoverable: boolean;
 
    procedure
SetConnectable(const Value: boolean);
    procedure
SetDiscoverable(const Value: boolean);
 
 
public
   
constructor Create(const AHandle: THandle);
    destructor
Destroy; override;
 
    property
Address: BTH_ADDR read FAddress;
    property
ClassOfDevice: cardinal read FClassOfDevice;
    property
Connectable: boolean read GetConnectable write SetConnectable;
    property
Discoverable: boolean read GetDiscoverable write SetDiscoverable;
    property
Handle: THandle read FHandle;
    property
Manufacturer: word read FManufacturer;
    property
Name: string read FName;
    property
Subversion: word read FSubversion;
 
end;
 
function BTGetRadioByAddr(const Addr: BTH_ADDR): TBTRadio;
 
procedure
BTEnumRadios(var Radios: TBTAddrArray);
 
implementation
 
uses
 
SysUtils, BTStrings, BTExceptions;
 
function BTGetRadioByAddr(const Addr: BTH_ADDR): TBTRadio;
var
  hFind
: HBLUETOOTH_RADIO_FIND;
 
SearchParams: BLUETOOTH_FIND_RADIO_PARAMS;
  hRadio
: THandle;
 
RadioInfo: BLUETOOTH_RADIO_INFO;
 
RadioInfoSize: dword;
begin
 
Result := nil;
 
 
SearchParams.dwSize := SizeOf(BLUETOOTH_FIND_RADIO_PARAMS);
 
  hFind
:= BluetoothFindFirstRadio(@SearchParams, hRadio);
 
if (hFind <> 0) then begin
    repeat
     
RadioInfoSize := SizeOf(BLUETOOTH_RADIO_INFO);
     
FillChar(RadioInfo, RadioInfoSize, 0);
     
RadioInfo.dwSize := RadioInfoSize;
 
     
if (BluetoothGetRadioInfo(hRadio, RadioInfo) = ERROR_SUCCESS) then
       
if (RadioInfo.address.ullLong = Addr) then begin
         
Result := TBTRadio.Create(hRadio);
         
Break;
       
end;
 
     
CloseHandle(hRadio);
   
until (not BluetoothFindNextRadio(hFind, hRadio));
 
   
BluetoothFindRadioClose(hFind);
 
end;
end;
 
procedure
BTEnumRadios(var Radios: TBTAddrArray);
var
  hFind
: HBLUETOOTH_RADIO_FIND;
 
SearchParams: BLUETOOTH_FIND_RADIO_PARAMS;
  hRadio
: THandle;
 
Ndx: word;
 
RadioInfo: BLUETOOTH_RADIO_INFO;
 
RadioInfoSize: dword;
begin
 
Radios := nil;
 
Ndx := 0;
 
 
SearchParams.dwSize := SizeOf(BLUETOOTH_FIND_RADIO_PARAMS);
 
  hFind
:= BluetoothFindFirstRadio(@SearchParams, hRadio);
 
if (hFind <> 0) then begin
    repeat
     
RadioInfoSize := SizeOf(BLUETOOTH_RADIO_INFO);
     
FillChar(RadioInfo, RadioInfoSize, 0);
     
RadioInfo.dwSize := RadioInfoSize;
 
     
if (BluetoothGetRadioInfo(hRadio, RadioInfo) = ERROR_SUCCESS) then begin
       
Inc(Ndx);
       
SetLength(Radios, Ndx);
       
CopyMemory(@Radios[Ndx - 1], @RadioInfo, RadioInfoSize);
     
end;
 
     
CloseHandle(hRadio);
   
until (not BluetoothFindNextRadio(hFind, hRadio));
 
   
BluetoothFindRadioClose(hFind);
 
end;
end;
 
function TBTRadio.GetConnectable: boolean;
begin
 
Result := BluetoothIsConnectable(FHandle);
end;
 
function TBTRadio.GetDiscoverable: boolean;
begin
 
Result := BluetoothIsDiscoverable(FHandle);
end;
 
procedure
TBTRadio.SetConnectable(const Value: boolean);
begin
 
if (not BluetoothEnableIncomingConnections(FHandle, Value)) then raise BTException.Create(STR_ERROR_ENABLE_CONNECTION);
end;
 
procedure
TBTRadio.SetDiscoverable(const Value: boolean);
begin
 
if (not BluetoothEnableDiscovery(FHandle, Value)) then raise BTException.Create(STR_ERROR_ENABLE_DISCOVERY);
end;
 
constructor TBTRadio.Create(const AHandle: THandle);
var
 
RadioInfo: BLUETOOTH_RADIO_INFO;
 
RadioInfoSize: dword;
 
Res: dword;
begin
 
FHandle := AHandle;
 
 
RadioInfoSize := SizeOf(BLUETOOTH_RADIO_INFO);
 
FillChar(RadioInfo, RadioInfoSize, 0);
 
RadioInfo.dwSize := RadioInfoSize;
 
 
Res := BluetoothGetRadioInfo(FHandle, RadioInfo);
 
if (Res = ERROR_SUCCESS) then begin
   
FAddress := RadioInfo.address.ullLong;
   
FClassOfDevice := RadioInfo.ulClassofDevice;
   
FManufacturer := RadioInfo.manufacturer;
   
FName := string(widestring(RadioInfo.szName));
   
FSubversion := RadioInfo.lmpSubversion;
 
 
end else
   
case Res of
      ERROR_INVALID_PARAMETER
: raise BTException.Create(STR_ERROR_INVALID_PARAMETER);
      ERROR_REVISION_MISMATCH
: raise BTException.Create(STR_ERROR_REVISION_MISMATCH);
 
   
else
     
RaiseLastOSError;
   
end;
end;
 
destructor
TBTRadio.Destroy;
begin
 
CloseHandle(FHandle);
 
  inherited
;
end;
 
end.
 
{
 
Copyright (C) 2006 Mike B. Petrichenko
  pmb_stv@mail
.ru
  mobileservicesoft@yandex
.ru
  ICQ
: 190812766
 
Phone: +7 (928) 324-58-24
         
+7 (928) 819-46-40
 
 
All Rights Reserved.
 
 
Only for non commercial purpose.
}
unit
BTStrings;
 
interface
 
resourcestring
  STR_ERROR_INVALID_PARAMETER    
= 'The hRadio or pRadioInfo parameter is NULL.';
  STR_ERROR_REVISION_MISMATCH    
= 'The dwSize member of the BLUETOOTH_RADIO_INFO structure pointed to by pRadioInfo is not valid.';
  STR_ERROR_ENABLE_CONNECTION    
= 'Unable change incoming connection state.';
  STR_ERROR_ENABLE_DISCOVERY      
= 'Unable change discovery state';
  STR_ERROR_REVISION_MISMATCH_DEV
= 'The size of the BLUETOOTH_DEVICE_INFO is not compatible. Check the dwSize member of the BLUETOOTH_DEVICE_INFO structure.';
  STR_ERROR_NOT_FOUND                  
= 'The radio is not known by the system, or the Address member of the BLUETOOTH_DEVICE_INFO structure is all zeros.';
  STR_ERROR_INVALID_PARAMETER_DEV
= 'The pbtdi parameter is NULL.';
  STR_ERROR_INVALID_PARAMETER_SEL
= 'The pbtsdp is NULL.';
  STR_ERROR_REVISION_MISMATCH_SEL
= 'The structure passed in as pbtsdp is of an unknown size.';
 
implementation
 
end.