B. *_*per 4 python linux android bluetooth
我正在开发一个将 Android 设备与 Raspberry Pi 连接的项目。RPi 需要被视为用户永远不需要触摸的可部署设备。出于这个原因,我尝试在 RPi 上编写一个启动批处理脚本,该脚本将允许用户将其 Android 与 PI 配对。
我的想法是,当您启动时,此脚本将运行,手机上的用户将尝试连接到 RPi,并且 RPi 将自动接受此连接。
这是我到目前为止所拥有的
#!/bin/bash
bluetoothctl -- discoverable on
bluetoothctl -- pairable on
bluetoothctl -- agent on
bluetoothctl -- default-agent
Run Code Online (Sandbox Code Playgroud)
问题是,当我这样做时,我没有进入[bluetoothctl]需要与 Android 通信的提示。
当我运行这些命令(没有批处理脚本)并尝试与我的 Android 配对时,我得到
Request confirmation
[agent] Confirm passkey 861797 (yes/no): yes
Run Code Online (Sandbox Code Playgroud)
从这里我只需输入 yes 即可实例化连接。我看到的问题是 1:我不知道如何留在[bluetoothctl]命令行中的提示中与设备通信;2:我不知道如何向提示发送“是”。
同样,对我来说重要的是,用户除了出于部署目的而启动 RPi 之外,无需对 RPi 执行任何其他操作。有没有解决我的问题的方法,或者也许有更好的方法来同时完成这一切?
对于那些感兴趣的人来说,蓝牙启动连接已就位,以便我可以将网络信息发送到 RPi,并且它可以自动将自身连接到网络,以便主要应用程序通信将以这种方式进行。
这是我能够手动执行的脚本的预期结果。
以这种方式使用bluetoothctl可能会出现问题,因为它不是设计为以这种方式进行交互的。由于您已将 Python 作为标签之一,因此从 Python(和其他语言)访问此功能的预期方法是通过 D-Bus API。
这些记录在:https ://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc
有示例:https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test
确认是在代理 APIRequestConfirmation中进行的。您还可以使用适配器 API设置可发现和可配对。使用 API 还可以让您避免发现超时。
手机连接后,您通常希望将其标记为可信,以便不需要再次配对。这是通过设备 API完成的。
下面是使用 Python 在适配器上设置这些属性的示例。我保留了所有代理功能,尽管它只是 RequestConfirmation使用的功能。我已将其设置为始终同意发送的任何代码,这就是您在问题中所要求的。
此示例 Python 脚本将替换您的批处理脚本
import dbus
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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3897 次 |
| 最近记录: |