使用 Bluez-obex 和 pydbus 的 Python opp obex 服务器?

Posted

技术标签:

【中文标题】使用 Bluez-obex 和 pydbus 的 Python opp obex 服务器?【英文标题】:Python opp obex server using Bluez-obex and pydbus? 【发布时间】:2021-10-03 09:48:51 【问题描述】:

对于我的项目,我需要通过蓝牙下载 .zip 文件。我为此使用python和obex。我实现了一个工作的 python opp 客户端(向 ukBaz 求助),但我仍然使用 os 来启动服务器,所以我的服务器程序的其余部分不知道何时收到文件。程序的其余部分完成了,但是没有服务器的输出,我无法触发解压缩功能运行。我已经阅读了 bluez-obex API 文档,似乎没有关于启动服务器的任何内容。还有另一种方法吗?我的代码如下。

os.system("sudo obexpushd -B -o /home/pi/Desktop/ -n")

【问题讨论】:

【参考方案1】:

我不熟悉 obexpushd 以及使用 obexd 提供的功能时它为您提供的功能。

我的理解是您需要创建一个obex-agent 来接受/拒绝带有obexd 的蓝牙对象推送请求。

监控InterfacesAdded DBus 信号应该会为您提供传输开始时需要知道的信息。然后,您可以监视PropertiesChanged 信号以了解状态何时发生变化。

我能够将照片从手机推送到 Raspberry Pi,并在 RPi 上运行以下命令(我的手机和 RPi 已经配对):

from gi.repository import GLib
import pydbus

BUS_NAME = 'org.bluez.obex'
PATH = '/org/bluez/obex'
AGENT_MANAGER_INTERFACE = 'org.bluez.obex.AgentManager1'
AGENT_INTERFACE = 'org.bluez.obex.Agent1'
SESSION_INTERFACE = 'org.bluez.obex.Session1'
TRANSFER_INTERFACE = 'org.bluez.obex.Transfer1'

ses_bus = pydbus.SessionBus()


def transfer_status_handler(iface, props_changed, props_removed):
    if iface == TRANSFER_INTERFACE:
        status = props_changed.get('Status')
        if status == 'complete':
            print('Transfer complete')
        elif status == 'queued':
            print('Still queued')
        elif status == 'active':
            print('transferring')
        elif status == 'suspended':
            print('Suspended')
        elif status == 'error':
            print('error')

def iface_added_handler(dbus_path, interfaces):
    if SESSION_INTERFACE in interfaces and 'server' in dbus_path:
        print('Server session added')
    elif TRANSFER_INTERFACE in interfaces and 'server' in dbus_path:
        print('Transfer started')
        transfer = ses_bus.get(BUS_NAME, dbus_path)
        transfer.onPropertiesChanged = transfer_status_handler


class Agent:
    """
      <node>
        <interface name='org.bluez.obex.Agent1'>
          <method name='Release'>
          </method>
          <method name='AuthorizePush'>
            <arg type='s' name='path' direction='out'/>
            <arg type='o' name='transfer' direction='in'/>
          </method>
          <method name='Cancel'>
          </method>
        </interface>
      </node>
    """
    def AuthorizePush(self, path):
        print('Authorize Push', path)
        transfer = ses_bus.get(BUS_NAME, path)
        props = transfer.GetAll(TRANSFER_INTERFACE)
        print(props)
        return props.get('Name')

    def Cancel(self):
        print('Authorization Cancelled')

    def Release(self):
        pass


if __name__ == '__main__':
    obex_mngr = ses_bus.get('org.bluez.obex', '/')
    obex_mngr.onInterfacesAdded = iface_added_handler
    mainloop = GLib.MainLoop()
    ses_bus.register_object('/test/agent', Agent(), None)
    print('Agent created')
    agnt_mngr = ses_bus.get(BUS_NAME, PATH)
    agnt_mngr.RegisterAgent('/test/agent')
    print('Agent registered')
    try:
        mainloop.run()
    except KeyboardInterrupt:
        mainloop.quit()

此代码只接受由它发出的任何请求。这可能是一件坏事,如果文件应该被接受,人们可能想要添加一些检查(或提示用户)。

【讨论】:

我将代码变成了一个类,并试图将 AuthorizePush 函数中的路径更改为不同的目录,但它抛出了KeyError: 'object does not export any interfaces; you might need to pass object path as the 2nd argument for get()'。我查看了代理文档,所以此路径不应该是存储传输文件的位置吗?我的代码是这个问题:***.com/q/68552848/16532334

以上是关于使用 Bluez-obex 和 pydbus 的 Python opp obex 服务器?的主要内容,如果未能解决你的问题,请参考以下文章

Pydbus 更多通知同时处理

推荐使用 pydbus 或 dbus-python 有啥区别?

Pydbus中不同数量的参数

wpa_supplicant 没有接口(pydbus)

在 PyDbus 模拟中使用私有 DBus 连接

运行 pydbus 服务时如何获取发件人(客户端进程)