【问题标题】:Python PyBluez connecting to passkey protected devicePython PyBluez 连接到受密码保护的设备
【发布时间】:2013-06-09 23:58:36
【问题描述】:

我正在使用 Python 开发一个应用程序(当前是 2.7,如果需要可以切换到 3.3),它应该:

  1. 检测蓝牙设备(指夹脉搏血氧仪,如果您有兴趣)。
  2. 与设备建立连接(受密码保护)
  3. 将数据从设备流式传输到我的计算机
  4. 对数据进行更多(当前无关的)编程

为了实现这一点,我使用 Python 的 PyBluez 库,因为它可能是我找到的与 Windows 和 Python2.7 兼容的文档最多的库(遗憾的是仍然很少)。

我对套接字编程很陌生,所以这可能是一个简单的问题。我遇到的问题是我似乎无法弄清楚如何连接到设备,因为它受密码保护。我可以毫无问题地找到它并检索它的地址,我只是不知道连接时使用哪个端口或如何输入密码。

感谢您的帮助!

参考信息:
使用的脉搏血氧仪:http://www.echostore.com/wireless-oximeter-cms50e.html
PyBluez 库:http://pybluez.googlecode.com/svn/www/docs-0.7/index.html

【问题讨论】:

    标签: python sockets python-2.7 bluetooth bluez


    【解决方案1】:

    我遇到了同样的问题,我已经解决了,也许你可以试试:

    1. 制作一个名为pairtool.exe的windows工具,它可以帮助你与命令行配对。

      dwRet = BluetoothAuthenticateDevice(NULL, NULL, &btdi, L"1234", 4);
      if(dwRet != ERROR_SUCCESS)
      {
          fprintf(stderr, "BluetoothAuthenticateDevice ret %d\n", dwRet);
          ExitProcess(2);
      }
      
    2. python 代码:

      def connect2Btdev(devName):
      #found the device addr
      addr = inquiry(devName)
      if addr == None:
         return None
      
      #pairing with pairtool.exe
      cmd=r'%s %s' % ('pairtool.exe',addr)
      ret = os.system(cmd)
      
      if ret <> 0:
          return None
      

    【讨论】:

      【解决方案2】:

      PyBlueZ 没有在此处公开 Windows 蓝牙身份验证 API:https://msdn.microsoft.com/en-us/library/windows/desktop/cc766819(v=vs.85).aspx

      解决此问题的一种方法是创建一个命令行工具并通过 Python 使用它。要为 Windows 创建命令行工具,请使用 Visual Studio 并将必要的库添加到您的项目链接器属性:Bthprops.lib 和 ws2_32.lib

      下面是一个项目的代码,用于制作一个带有 1 个参数的命令行工具,即 MAC 地址,它使用“Just Works”配对来配对指定的设备。请参阅使用密钥配对的注释代码。

      #include "stdafx.h"
      #include <initguid.h>
      #include <winsock2.h>
      #include <BluetoothAPIs.h>
      #include <ws2bth.h>
      
      BOOL WINAPI BluetoothAuthCallback(LPVOID pvParam, PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS pAuthCallbackParams);
      
      int _tmain(int argc, _TCHAR* argv[])
      {
          SOCKADDR_BTH sa = { 0 };
          int sa_len = sizeof(sa);
          DWORD dwRet;
          BLUETOOTH_DEVICE_INFO  btdi = { 0 };
          HBLUETOOTH_AUTHENTICATION_REGISTRATION hRegHandle = 0;
      
          // initialize windows sockets
          WORD wVersionRequested;
          WSADATA wsaData;
          wVersionRequested = MAKEWORD(2, 0);
          if (WSAStartup(wVersionRequested, &wsaData) != 0) {
              ExitProcess(2);
          }
      
          // parse the specified Bluetooth address
          if (argc < 2) {
              fprintf(stderr, "usage: csbtpair <addr>\n"
                  "\n  addr must be in the form (XX:XX:XX:XX:XX:XX)");
              ExitProcess(2);
          }
          if (SOCKET_ERROR == WSAStringToAddress(argv[1], AF_BTH,
              NULL, (LPSOCKADDR)&sa, &sa_len)) {
              ExitProcess(2);
          }
      
          // setup device info
          btdi.dwSize = sizeof(BLUETOOTH_DEVICE_INFO);
          btdi.Address.ullLong = sa.btAddr;
          btdi.ulClassofDevice = 0;
          btdi.fConnected = false;
          btdi.fRemembered = false;
          btdi.fAuthenticated = false;
      
          // register authentication callback. this prevents UI from showing up.
          dwRet = BluetoothRegisterForAuthenticationEx(&btdi, &hRegHandle, &BluetoothAuthCallback, NULL);
          if (dwRet != ERROR_SUCCESS)
          {
              fprintf(stderr, "BluetoothRegisterForAuthenticationEx ret %d\n", dwRet);
              ExitProcess(2);
          }
      
          // authenticate device (will call authentication callback)
          AUTHENTICATION_REQUIREMENTS authreqs = MITMProtectionNotRequired;
          fprintf(stderr, "BluetoothAuthReqs = %d\n", authreqs);
          dwRet = BluetoothAuthenticateDeviceEx(NULL, NULL, &btdi, NULL, authreqs);
          if (dwRet != ERROR_SUCCESS)
          {
              fprintf(stderr, "BluetoothAuthenticateDevice ret %d\n", dwRet);
              if (dwRet == ERROR_CANCELLED)
              {
                  fprintf(stderr, "Cancelled");
              }
              else if (dwRet == ERROR_INVALID_PARAMETER)
              {
                  fprintf(stderr, "Invalid Parameter");
              }
              else if (dwRet == ERROR_NO_MORE_ITEMS)
              {
                  fprintf(stderr, "Already paired!");
              }
          }
      
          fprintf(stderr, "pairing finish\n");
          ExitProcess(0);
          return 0;
      }
      
      // Authentication callback
      BOOL WINAPI BluetoothAuthCallback(LPVOID pvParam, PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS pAuthCallbackParams)
      {
          DWORD dwRet;
      
          fprintf(stderr, "BluetoothAuthCallback 0x%x\n", pAuthCallbackParams->deviceInfo.Address.ullLong);
          BLUETOOTH_AUTHENTICATE_RESPONSE AuthRes;
          AuthRes.authMethod = pAuthCallbackParams->authenticationMethod;
          fprintf(stderr, "Authmethod %d\n", AuthRes.authMethod);
          // Check to make sure we are using numeric comparison (Just Works)
          if (AuthRes.authMethod == BLUETOOTH_AUTHENTICATION_METHOD_NUMERIC_COMPARISON) 
          {
              fprintf(stderr, "Numeric Comparison supported\n");
          }
          AuthRes.bthAddressRemote = pAuthCallbackParams->deviceInfo.Address;
          AuthRes.negativeResponse = FALSE;
      
          // Commented out code is used for pairing using the BLUETOOTH_AUTHENTICATION_METHOD_PASSKEY method
          //memcpy_s(AuthRes.pinInfo.pin, sizeof(AuthRes.pinInfo.pin), L"1234", 0);
          //AuthRes.pinInfo.pinLength = 0;
          // Respond with numerical value for Just Works pairing
          AuthRes.numericCompInfo.NumericValue = 1;
      
          // Send authentication response to authenticate device
          dwRet = BluetoothSendAuthenticationResponseEx(NULL, &AuthRes);
          if (dwRet != ERROR_SUCCESS)
          {
              fprintf(stderr, "BluetoothSendAuthenticationResponseEx ret %d\n", dwRet);
              if (dwRet == ERROR_CANCELLED)
              {
                  fprintf(stderr, "Bluetooth device denied passkey response or communicatino problem.\n");
              }
              else if (dwRet == E_FAIL)
              {
                  fprintf(stderr, "Device returned a failure code during authentication.\n");
              }
              else if (dwRet == 1244)
              {
                  fprintf(stderr, "Not authenticated\n");
              }
          }
          else
          {
              fprintf(stderr, "BluetoothAuthCallback finish\n");
          }
      
          return 1; // This value is ignored
      }
      

      代替自己创建这个,您可能想尝试这个预制的解决方案: http://bluetoothinstaller.com/bluetooth-command-line-tools/ 它不适用于我的特定解决方案。

      然后,您需要以管理员身份从 python 运行下载的或自定义的命令行工具。为了可靠地做到这一点,我推荐 stackoverflow 问题: How to run python script with elevated privilege on windows

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-03
        • 2012-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-23
        • 2016-10-22
        相关资源
        最近更新 更多