简体   繁体   English

Python PyBluez连接到受密码保护的设备

[英]Python PyBluez connecting to passkey protected device

I'm working on an application in Python (currently 2.7, can switch to 3.3 if necessary) that is supposed to: 我正在使用Python(目前为2.7,必要时可以切换到3.3)上的应用程序,该应用程序应该:

  1. Detect bluetooth device (finger clip pulse oximeter, if you're interested). 检测蓝牙设备(如果您有兴趣,请使用手指夹脉搏血氧仪)。
  2. Establish connection with device (which is passkey protected) 与设备建立连接(受密码保护)
  3. Stream data from the device to my computer 将数据从设备传输到我的计算机
  4. Do more (currenly irrelevant) programming with the data 对数据执行更多(可能无关)编程

To accomplish this, I'm using the PyBluez library for Python, as it is probably the most documented library I've found (which sadly is still quite little) that is compatible with Windows and Python2.7. 为此,我将PyBluez库用于Python,因为它可能是我发现的文档最多的库(遗憾的是,它仍然很少),它与Windows和Python2.7兼容。

I am very new to socket programming, so this is probably a simple question. 我是套接字编程的新手,所以这可能是一个简单的问题。 The issue I've encountered, is that I cannot seem to figure out how to connect to the device since it is passkey protected. 我遇到的问题是,由于受密码保护,我似乎无法弄清楚如何连接到该设备。 I can locate it and retrieve its address with no problem, I just don't know what port to use when connecting or how to enter a passkey. 我可以毫无问题地找到它并检索其地址,我只是不知道连接时要使用哪个端口或如何输入密码。

Thanks for your help! 谢谢你的帮助!

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

I meet the same problem,and I have resolved the problem, Maybe you can try it: 我遇到了同样的问题,并且已经解决了这个问题,也许您可​​以尝试一下:

  1. make a windows tool named pairtool.exe, it help you to pairing with command line. 制作一个名为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 code: 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 

PyBlueZ does not expose the windows Bluetooth authentication APIs here: https://msdn.microsoft.com/en-us/library/windows/desktop/cc766819(v=vs.85).aspx PyBlueZ不在此处公开Windows蓝牙身份验证API: https ://msdn.microsoft.com/zh-cn/library/windows/desktop/cc766819(v=vs.85).aspx

One way to get around this is to create a command line tool and use this through Python. 解决该问题的一种方法是创建一个命令行工具,并通过Python使用它。 To create command line tools for Windows, use Visual Studio and add the necessary libraries to your project linker properties: Bthprops.lib and ws2_32.lib 要为Windows创建命令行工具,请使用Visual Studio并将必要的库添加到项目链接器属性中:Bthprops.lib和ws2_32.lib

Below is the code for a project to make a command line tool with 1 parameter, the MAC address, that pairs the specified device using "Just Works" pairing. 以下是一个项目的代码,该项目使用1个参数(MAC地址)制作命令行工具,该参数使用“ Just Works”配对来配对指定的设备。 See commented code for using passkey pairing. 有关使用密钥配对的信息,请参见注释的代码。

#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
}

In lieu of creating this yourself, you may want to try this pre-made solution: http://bluetoothinstaller.com/bluetooth-command-line-tools/ It did not work for my particular solution. 代替自己创建一个,您可能想尝试以下预制的解决方案: http : //bluetoothinstaller.com/bluetooth-command-line-tools/它不适用于我的特定解决方案。

Then, you will need to run your downloaded or custom command line tool from python as an administrator. 然后,您将需要以管理员身份从python运行下载的或自定义的命令行工具。 To do this reliably, I recommend the stackoverflow question: How to run python script with elevated privilege on windows 为了可靠地执行此操作,我建议您使用stackoverflow问题: 如何在Windows上以提升的特权运行python脚本

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM