首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图将linux系统作为无头蓝牙服务器运行,该服务器要求连接的电话或平板电脑提供一个引脚。

试图将linux系统作为无头蓝牙服务器运行,该服务器要求连接的电话或平板电脑提供一个引脚。
EN

Stack Overflow用户
提问于 2022-02-24 14:53:07
回答 1查看 236关注 0票数 0

我正在使用一台linux计算机,在部署它时,它将无法与它进行接口。

唯一(最终用户友好的)接入点,它必须开始是一个蓝牙接入点。

蓝牙通信已经成功建立,手机可以与控制器连接,而无需对控制器进行任何输入。

问题是在这种情况下它是不安全的,任何东西现在都可以自由地配对和连接。

我希望控制器从连接设备中请求一个控制器唯一的引脚,这样只有访问到该引脚的人才能与控制器连接。

我使用python来管理处理配对过程的代理,目前我正在使用以下代码:

代码语言:javascript
复制
import dbus.service
import dbus.mainloop.glib
from gi.repository import GLib

BUS_NAME = 'org.bluez'
ADAPTER_IFACE = 'org.bluez.Adapter1'
ADAPTER_ROOT = '/org/bluez/hci'
AGENT_IFACE = 'org.bluez.Agent1'
AGNT_MNGR_IFACE = 'org.bluez.AgentManager1'
AGENT_PATH = '/my/app/agent'
AGNT_MNGR_PATH = '/org/bluez'
CAPABILITY = 'KeyboardDisplay'
DEVICE_IFACE = 'org.bluez.Device1'
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()

def set_trusted(path):
    props = dbus.Interface(bus.get_object(BUS_NAME, path), dbus.PROPERTIES_IFACE)
    props.Set(DEVICE_IFACE, "Trusted", True)

class Agent(dbus.service.Object):

    @dbus.service.method(AGENT_IFACE,
                         in_signature="", out_signature="")
    def Release(self):
        print("Release")

    @dbus.service.method(AGENT_IFACE,
                         in_signature='o', out_signature='s')
    def RequestPinCode(self, device):
        print(f'RequestPinCode {device}')
        return '0000'

    @dbus.service.method(AGENT_IFACE,
                         in_signature="ou", out_signature="")
    def RequestConfirmation(self, device, passkey):
        print("RequestConfirmation (%s, %06d)" % (device, passkey))
        set_trusted(device)
        return

    @dbus.service.method(AGENT_IFACE,
                         in_signature="o", out_signature="")
    def RequestAuthorization(self, device):
        print("RequestAuthorization (%s)" % (device))
        auth = input("Authorize? (yes/no): ")
        if (auth == "yes"):
            return
        raise Rejected("Pairing rejected")

    @dbus.service.method(AGENT_IFACE,
                         in_signature="o", out_signature="u")
    def RequestPasskey(self, device):
        print("RequestPasskey (%s)" % (device))
        set_trusted(device)
        passkey = input("Enter passkey: ")
        return dbus.UInt32(passkey)

    @dbus.service.method(AGENT_IFACE,
                         in_signature="ouq", out_signature="")
    def DisplayPasskey(self, device, passkey, entered):
        print("DisplayPasskey (%s, %06u entered %u)" %
              (device, passkey, entered))

    @dbus.service.method(AGENT_IFACE,
                         in_signature="os", out_signature="")
    def DisplayPinCode(self, device, pincode):
        print("DisplayPinCode (%s, %s)" % (device, pincode))


class Adapter:
    def __init__(self, idx=0):
        bus = dbus.SystemBus()
        self.path = f'{ADAPTER_ROOT}{idx}'
        self.adapter_object = bus.get_object(BUS_NAME, self.path)
        self.adapter_props = dbus.Interface(self.adapter_object,
                                            dbus.PROPERTIES_IFACE)
        self.adapter_props.Set(ADAPTER_IFACE,
                               'DiscoverableTimeout', dbus.UInt32(0))
        self.adapter_props.Set(ADAPTER_IFACE,
                               'Discoverable', True)
        self.adapter_props.Set(ADAPTER_IFACE,
                               'PairableTimeout', dbus.UInt32(0))
        self.adapter_props.Set(ADAPTER_IFACE,
                               'Pairable', True)


if __name__ == '__main__':
    agent = Agent(bus, AGENT_PATH)
    agnt_mngr = dbus.Interface(bus.get_object(BUS_NAME, AGNT_MNGR_PATH),
                               AGNT_MNGR_IFACE)
    agnt_mngr.RegisterAgent(AGENT_PATH, CAPABILITY)
    agnt_mngr.RequestDefaultAgent(AGENT_PATH)

    adapter = Adapter()
    mainloop = GLib.MainLoop()
    try:
        mainloop.run()
    except KeyboardInterrupt:
        agnt_mngr.UnregisterAgent(AGENT_PATH)
        mainloop.quit()

我从这里得到了这段代码,但老实说,我不明白。

它定义了一组dbus.service.Method,我认为它以某种方式选择了一个或什么。

作为一个习惯不那么抽象的语言的人,我只是不知道它把这些东西放在哪里,或者把它拉到哪里去。

在本例中,我相信它只是使用了RequestConfirmation()方法。所以其他的都是垃圾。

但是我想知道,当我试图和控制器配对时,我是否可以/如何修改它,让它在我的手机上要求一个引脚或密码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-24 16:48:47

为了解释密码在做什么..。

在Linux系统上运行着蓝牙守护进程(bluetoothd)。bluetoothd处理系统上的蓝牙功能。下面是用于配对的与bluetoothd交互的顺序图。

RegisterAgent()用于告诉bluetoothd在哪里创建了D-Bus org.bluez.Agent1接口,以及使用该注册代理的能力。

当配对请求传入bluetoothd时,它会在注册位置调用RequestConfirmation()。如果返回的值为空,则确认确认。如果有org.bluez.Error.Rejectedorg.bluez.Error.Canceled抛出,则拒绝配对。

org.bluez.Agent1方法中的哪些方法由bluetoothd调用将取决于收到了哪种类型的配对请求。

功能设置可能最好由这个表格来总结。

如果调用的是RequestConfirmation()方法,则设备D总线路径和uint32密码键是传入的参数。要由代理中的方法来决定是否接受该请求。

org.bluez.Agent1接口记录在:

https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/agent-api.txt

简单代理的官方BlueZ示例位于:

https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/simple-agent

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71253860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档