先前直接運行bt-agent --capability=NoInputNoOutput 實現(xiàn)了功能肩祥,但是發(fā)現(xiàn)一個bug混狠,手機端連接成功后疾层,斷開連接取消配對痛黎,再次重新嘗試配對再也不會成功了,會提示配對失敗桌肴∽蛊撸可能是bt-agent tool的bug旗笔, 只得再想其他更完善的解決辦法蝇恶。
按如下方式python實現(xiàn)agent撮弧,可以達到想要的效果,多次測試取消配對授舟、忽略設(shè)備后都可以再次重新配對成功释树。
創(chuàng)建bt_agent.py
sudo vim /usr/local/bin/bt_agent.py
代碼
import dbus
import dbus.service
import dbus.mainloop.glib
from gi.repository import GLib
import time
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'#'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)
def agent_setup():
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()
if __name__ == '__main__':
try:
agent_setup()
except:
print("Try again in 20 seconds")
time.sleep(20)
agent_setup()
創(chuàng)建service文件
sudo vim /etc/systemd/system/btagent_py.service
文件內(nèi)容
[Unit]
Description=Bt Agent Py Auto Service
After=bluetooth.service
Requires=bluetooth.service
[Service]
# 下面兩行設(shè)定了再開機后120秒再啟動服務(wù)
TimeoutStartSec=infinity
ExecStartPre=/bin/sleep 120
Restart=on-failure
RestartSec=5s
ExecStart=python3 /usr/local/bin/bt_agent.py
[Install]
WantedBy=multi-user.target
啟動服務(wù)并設(shè)置開機自啟
sudo systemctl daemon-reload
sudo systemctl start btagent_py.service
sudo systemctl enable btagent_py.service
重啟系統(tǒng)檢查是否成功自動運行
sudo systemctl status btagent_py.service
停止該服務(wù)并禁用開機自啟
如果要取消自啟動可按如下操作:
sudo systemctl stop btagent_py.service
sudo systemctl disable btagent_py.service