title: Pairing a bluetooth device in windows with c++
body: <p>I need to be able to pair a device using code in C++ for windows (specifically win7 or newer).  I have written the code that should work but it doesn't.  I can pair a lot of devices, a Roku, a headset, speakers, etc, but for some reason the device I need to pair will not work.</p>
  
  <p>It always returns an error code of 0x05 which according to bthdefs.h is defined as BTH_ERROR_AUTHENTICATION_FAILURE.  </p>
  
  <p>So the weird part here.  It never tries to authenticate.  The callback function that should get called to provide the passkey during pairing doesn't get called.  I have verified it does get called with other devices like a headset.</p>
  
  <p>I have tried using BluetoothAuthenticateDeviceEx() without the callback function which <em>should</em> pop up the GUI in windows to finish the pairing.  It pops up for my headset and other devices, it won't pop up for my device.</p>
  
  <p>As a side note I can pair the device using Window's bluetooth wizard just fine.  It just refuses to work programmatically.</p>
  
  <p>I can't figure out what the difference is between the winapi code I am using and what windows' wizard is doing during pairing.</p>
  
  <p>Here is the simplest test app I could get.  My real app was using Qt and mingw to build.  This app uses MSVC 2012 and pure windows code to remove any obfuscation from the problem.  All my code has the same problems with that error code 5.</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include "bthdef.h"
  #include "BluetoothAPIs.h"
  #include &lt;tchar.h&gt;
  #include &lt;string&gt;
  #include &lt;iostream&gt;
  #include &lt;vector&gt;
  
  #pragma comment(lib, "bthprops.lib")
  
  using namespace std;
  
  vector&lt;BLUETOOTH_DEVICE_INFO&gt; scanDevices()
  {
      vector&lt;BLUETOOTH_DEVICE_INFO&gt; res;
  
      BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp;
      BLUETOOTH_DEVICE_INFO bdi;
      HBLUETOOTH_DEVICE_FIND hbf;
  
      ZeroMemory(&amp;bdsp, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS));
  
      // set options for how we want to load our list of BT devices
      bdsp.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
      bdsp.fReturnAuthenticated = TRUE;
      bdsp.fReturnRemembered = TRUE;
      bdsp.fReturnUnknown = TRUE;
      bdsp.fReturnConnected = TRUE;
      bdsp.fIssueInquiry = TRUE;
      bdsp.cTimeoutMultiplier = 4;
      bdsp.hRadio = NULL;
  
      bdi.dwSize = sizeof(bdi);
  
      // enumerate our bluetooth devices
      hbf = BluetoothFindFirstDevice(&amp;bdsp, &amp;bdi);
      if (hbf)
      {
          do
          {
              res.push_back(bdi);
          } while (BluetoothFindNextDevice(hbf, &amp;bdi));
  
          // close our device enumerator
          BluetoothFindDeviceClose(hbf);
      }
  
      return res;
  }
  
  BOOL CALLBACK bluetoothAuthCallback(LPVOID param, PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS params)
  {
      cout &lt;&lt; "callback happened" &lt;&lt; endl;
      return TRUE;
  }
  
  void pairDevice(BLUETOOTH_DEVICE_INFO device)
  {
      wstring ws = device.szName;
      cout &lt;&lt; "Pairing device " &lt;&lt; string(ws.begin(), ws.end()) &lt;&lt; endl;
  
      // register callback
      cout &lt;&lt; "Registering callback" &lt;&lt; endl;
      HBLUETOOTH_AUTHENTICATION_REGISTRATION hCallbackHandle = 0;
      DWORD result = BluetoothRegisterForAuthenticationEx(&amp;device, &amp;hCallbackHandle, (PFN_AUTHENTICATION_CALLBACK_EX)&amp;bluetoothAuthCallback, NULL);
      if (result != ERROR_SUCCESS)
      {
          cout &lt;&lt; "Failed to register callback" &lt;&lt; endl;
          return;
      }
  
      // authenticate
      result = BluetoothAuthenticateDeviceEx(NULL, NULL, &amp;device, NULL, MITMProtectionNotRequired);
      //DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &amp;device, NULL, MITMProtectionRequired);
      //DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &amp;device, NULL, MITMProtectionNotRequiredBonding);
      //DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &amp;device, NULL, MITMProtectionRequiredBonding);
      //DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &amp;device, NULL, MITMProtectionNotRequiredGeneralBonding);
      //DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &amp;device, NULL, MITMProtectionRequiredGeneralBonding);
      //DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &amp;device, NULL, MITMProtectionNotDefined);
      switch (result)
      {
      case ERROR_SUCCESS:
          cout &lt;&lt; "pair device success" &lt;&lt; endl;
          break;
  
      case ERROR_CANCELLED:
          cout &lt;&lt; "pair device failed, user cancelled" &lt;&lt; endl;
          break;
  
      case ERROR_INVALID_PARAMETER:
          cout &lt;&lt; "pair device failed, invalid parameter" &lt;&lt; endl;
          break;
  
      case ERROR_NO_MORE_ITEMS:
          cout &lt;&lt; "pair device failed, device appears paired already" &lt;&lt; endl;
          break;
  
      default:
          cout &lt;&lt; "pair device failed, unknown error, code " &lt;&lt; (unsigned int)result &lt;&lt; endl;
          break;
      }
  }
  
  int _tmain(int argc, _TCHAR *argv[])
  {
      cout &lt;&lt; "Scanning bluetooth devices..." &lt;&lt; endl;
      cout.flush();
  
      // scan devices
      vector&lt;BLUETOOTH_DEVICE_INFO&gt; devices = scanDevices();
  
      cout &lt;&lt; "Got " &lt;&lt; devices.size() &lt;&lt; " devices" &lt;&lt; endl;
  
      // list all devices
      int pdIndex = -1;
      int foundDev = -1;
      vector&lt;BLUETOOTH_DEVICE_INFO&gt;::const_iterator devci;
      for (devci=devices.begin();devci!=devices.end();devci++)
      {
          pdIndex++;
          wstring ws = (*devci).szName;
          cout &lt;&lt; "Device: " &lt;&lt; string(ws.begin(), ws.end()) &lt;&lt; endl;
  
          // see if we find our device (case sensitive)
          if (ws.find(L"smp") != string::npos)
              foundDev = pdIndex;
      }
  
      // pick our ismp device
      if (foundDev == -1)
      {
          cout &lt;&lt; "Could not find a device to pair" &lt;&lt; endl;
          return 1;
      }
  
      BLUETOOTH_DEVICE_INFO pd = devices[foundDev];
      wstring ws = pd.szName;
      cout &lt;&lt; "Found device to pair, " &lt;&lt; string(ws.begin(), ws.end()) &lt;&lt; endl;
  
      // attempt to pair device
      pairDevice(pd);
  
      return 0;
  }
  </code></pre>