Используя Raspberry Pi Zero 2W, с Ubuntu Bookworm Lite, у меня есть 2 программы, одна в Python и одна в C#. Они оба делают одно и то же (я переключается между одним и другим для тестирования): реализуйте агент для Bluez и зарегистрируюсь через DBU и обрабатываю функции спаривания. Версия Python должным образом получает вызов запроса Confirmation и отображает PassKey. Когда версия C# запускается, существует ошибка DBUS, в которой указывается, что: метод «requestConfirmation» с подписью «OU» на интерфейсе »org.bluez.agent1» не существует. < /P>
версии. < /h3>
[*] debian gnu /linux 12 (bookworm) - ядро: linux 6.6.51+rpt -rpi -v8 - arm64 < /li>
< li> dotnet 9 с tmds.dbus v0.21.2 (построено на Windows для Target Linux 64)
[*] Python 3.11.2
Bluez 5.66
Примечание: оба приложения запускаются с Sudo, чтобы получить доступ к системе dbus < /li>
< /ul>
Вот 2 реализации: < /p>
версия Python < /h3>
#!/usr/bin/env python3
import dbus
import dbus.exceptions
import dbus.mainloop.glib
import dbus.service
from gi.repository import GLib
AGENT_PATH = "/com/kevinisabelle/gamepad/agent"
class Agent(dbus.service.Object):
AGENT_INTERFACE = "org.bluez.Agent1"
def __init__(self, bus, path=AGENT_PATH):
dbus.service.Object.__init__(self, bus, path)
@dbus.service.method(AGENT_INTERFACE, in_signature="", out_signature="")
def Release(self):
print("Agent Released")
@dbus.service.method(AGENT_INTERFACE, in_signature="o", out_signature="u")
def RequestPasskey(self, device):
# Not used in JustWorks; return a dummy passkey.
print("RequestPasskey for device:", device)
return dbus.UInt32(0)
@dbus.service.method(AGENT_INTERFACE, in_signature="ou", out_signature="")
def DisplayPasskey(self, device, passkey):
# No display needed for JustWorks.
print("DisplayPasskey for device:", device, passkey)
@dbus.service.method(AGENT_INTERFACE, in_signature="ou", out_signature="")
def RequestConfirmation(self, device, passkey):
print("Auto-confirming pairing for device:", device, "with passkey:", passkey)
# Simply return without raising an exception.
return
@dbus.service.method(AGENT_INTERFACE, in_signature="o", out_signature="s")
def RequestPinCode(self, device):
# Return a dummy PIN if requested.
print("RequestPinCode for device:", device)
return "0000"
@dbus.service.method(AGENT_INTERFACE, in_signature="o", out_signature="")
def RequestAuthorization(self, device):
# Auto-authorize pairing.
print("RequestAuthorization for device:", device)
return
# --- Add the missing method ---
@dbus.service.method(AGENT_INTERFACE, in_signature="os", out_signature="")
def AuthorizeService(self, device, uuid):
print("AuthorizeService called for device {} and service UUID {}".format(device, uuid))
# Auto-authorize the service request.
return
def register_agent(bus, capability="KeyboardDisplay"):
try:
manager = dbus.Interface(
bus.get_object("org.bluez", "/org/bluez"),
"org.bluez.AgentManager1")
manager.RegisterAgent(AGENT_PATH, capability)
manager.RequestDefaultAgent(AGENT_PATH)
print("Agent registered as default with {} capability".format(capability))
except Exception as e:
print("Failed to register agent:", e)
def main():
print("Starting pairing agent...")
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
# Register our DisplayYesNo pairing agent
agent = Agent(bus)
register_agent(bus, "KeyboardDisplay")
# Enable adapter pairing and discovery (if not already enabled)
try:
adapter = bus.get_object("org.bluez", "/org/bluez/hci0")
props_iface = dbus.Interface(adapter, "org.freedesktop.DBus.Properties")
props_iface.Set("org.bluez.Adapter1", "Powered", dbus.Boolean(True))
props_iface.Set("org.bluez.Adapter1", "Discoverable", dbus.Boolean(True))
props_iface.Set("org.bluez.Adapter1", "Pairable", dbus.Boolean(True))
try:
props_iface.Set("org.bluez.Adapter1", "MinConnectionInterval", dbus.UInt16(6)) # 7.5ms
props_iface.Set("org.bluez.Adapter1", "MaxConnectionInterval", dbus.UInt16(16)) # 20ms
props_iface.Set("org.bluez.Adapter1", "ConnectionLatency", dbus.UInt16(0))
props_iface.Set("org.bluez.Adapter1", "SupervisionTimeout", dbus.UInt16(500)) # 5s
except Exception as e:
print("Warning: Could not set connection parameters:", e)
print("Adapter set to Powered, Discoverable, and Pairable")
except Exception as e:
print("Error setting adapter properties:", e)
loop = GLib.MainLoop()
print("Running main loop")
loop.run()
if __name__ == "__main__":
main()
< /code>
версия C# < /h3>
using Tmds.DBus;
namespace AgentOnly;
// -------------------------------
// Define the D-Bus interfaces
// -------------------------------
[DBusInterface("org.bluez.Agent1")]
public interface IAgent1 : IDBusObject
{
// Called when the agent is unregistered.
Task ReleaseAsync();
// Called to request a numeric passkey for pairing.
// (Returns a uint between 0 and 999999.)
Task RequestPasskeyAsync(ObjectPath device);
// Called to display a passkey; expects a uint passkey.
Task DisplayPasskeyAsync(ObjectPath device, uint passkey);
// Called to request confirmation of a passkey.
// (Here, we expect the passkey to be passed as a string, matching the Python "os" signature.)
Task RequestConfirmationAsync(ObjectPath device, uint passkey);
// Called to request a PIN code; returns a string PIN.
Task RequestPinCodeAsync(ObjectPath device);
// Called to request authorization for pairing.
Task RequestAuthorizationAsync(ObjectPath device);
// Called to authorize a service request; takes a device and a service UUID.
Task AuthorizeServiceAsync(ObjectPath device, string uuid);
Task CancelAsync();
}
// For agent registration
[DBusInterface("org.bluez.AgentManager1")]
public interface IAgentManager1 : IDBusObject
{
Task RegisterAgentAsync(ObjectPath agentPath, string capability);
Task RequestDefaultAgentAsync(ObjectPath agentPath);
}
[DBusInterface("org.bluez.Adapter1")]
public interface IAdapter1 : IDBusObject
{
Task SetAsync(string propertyName, object value);
}
// -------------------------------
// Implement the service classes
// -------------------------------
// Agent for pairing
[DBusInterface("org.bluez.Agent1")]
public class Agent1 : IAgent1
{
public ObjectPath ObjectPath { get; }
public Agent1(ObjectPath path) { ObjectPath = path; }
public Task ReleaseAsync()
{
Console.WriteLine("Agent Released");
return Task.CompletedTask;
}
public Task RequestPinCodeAsync(ObjectPath device)
{
Console.WriteLine("Requesting PIN code for device: " + device);
return Task.FromResult("0000");
}
public Task DisplayPinCodeAsync(ObjectPath device, string pincode)
{
Console.WriteLine("Displaying PIN code for device: " + device + " PIN: " + pincode);
return Task.CompletedTask;
}
public Task RequestPasskeyAsync(ObjectPath device)
{
Console.WriteLine("Requesting passkey for device: " + device);
return Task.FromResult((uint)123456);
}
public Task DisplayPasskeyAsync(ObjectPath device, uint passkey)
{
Console.WriteLine("Displaying passkey for device: " + device + " Passkey: " + passkey);
return Task.CompletedTask;
}
public Task RequestConfirmationAsync(ObjectPath device, uint passkey)
{
Console.WriteLine("Requesting confirmation for device: " + device + " Passkey: " + passkey);
return Task.CompletedTask;
}
public Task RequestAuthorizationAsync(ObjectPath device)
{
Console.WriteLine("Requesting authorization for device: " + device);
return Task.CompletedTask;
}
public Task AuthorizeServiceAsync(ObjectPath device, string uuid)
{
Console.WriteLine("Authorizing service for device: " + device + " UUID: " + uuid);
return Task.CompletedTask;
}
public Task CancelAsync()
{
Console.WriteLine("Agent request cancelled");
return Task.CompletedTask;
}
}
// -------------------------------
// Main program and registration helpers
// -------------------------------
public class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Starting BlueZ Agent...");
var connection = new Connection(Address.System);
await connection.ConnectAsync();
var agent = new Agent1(new ObjectPath("/com/kevinisabelle/agent"));
var capability = "KeyboardDisplay";
await connection.RegisterObjectAsync(agent);
if (args.Length > 0 && args[0] == "register")
{
var agentManager = connection.CreateProxy("org.bluez", new ObjectPath("/org/bluez"));
await agentManager.RegisterAgentAsync(agent.ObjectPath, capability);
Console.WriteLine("Agent registered with capability: " + capability);
await Task.Delay(1000);
await agentManager.RequestDefaultAgentAsync(agent.ObjectPath);
Console.WriteLine($"Agent registered as default with {capability} capability");
}
try
{
var adapterProps = connection.CreateProxy("org.bluez", new ObjectPath("/org/bluez/hci0"));
await adapterProps.SetAsync("Powered", true);
await adapterProps.SetAsync("Discoverable", true);
await adapterProps.SetAsync("Pairable", true);
Console.WriteLine("Adapter set to Powered, Discoverable, and Pairable");
}
catch (Exception ex)
{
Console.WriteLine("Error setting adapter properties: " + ex.Message);
throw;
}
// Run forever
await Task.Delay(-1);
}
}
< /code>
Вещи, которые я уже проверил: < /p>
Различные типы для Uint passkey (пробое с int, string, ushort) , но uint - это то, что указано в DOC, и ошибка также говорит мне, что надлежащая подпись - «ou» (ObjectPath, Uint32) < /li>
Пробовал создать простой приемник DBUS и отправитель в C# to Убедитесь, что я могу на самом деле получать звонки в моем коде C# DBUS. Это работает нормально. < /Li>
подтвердил, что агент правильно зарегистрирован как агент по умолчанию, просматривая сообщения DBUS. Но кажется, что этот интерфейс не доступен за пределами Bluez, потому что я получаю тот же «без результата», использую ли я агент Python или агент C#. < /li>
< /ul>
Всегда одинаково, Python One в порядке, но C# One получает жалобу от DBU, что метод не существует. >
CAL :1.259(90)->:1.273 /com/kevinisabelle/agent org.bluez.Agent1.RequestConfirmation ou
- /org/bluez/hci0/dev_B0_A4_60_E7_88_52
- 262106
ERR :1.273(8)->:1.259(90) org.freedesktop.DBus.Error.UnknownMethod s
- Method "RequestConfirmation" with signature "ou" on interface "org.bluez.Agent1" doesn't exist
< /code>
, а также вот и журнал, когда мой агент запускается и зарегистрируется в Bluez: < /p>
SIG org.freedesktop.DBus(4)->:1.277 /org/freedesktop/DBus org.freedesktop.DBus.NameLost s
- :1.277
CAL :1.278(1)->org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.Hello
RET org.freedesktop.DBus(1)->:1.278(1) s
- :1.278
SIG org.freedesktop.DBus(511)-> /org/freedesktop/DBus org.freedesktop.DBus.NameOwnerChanged sss
- :1.278
-
- :1.278
SIG org.freedesktop.DBus(2)->:1.278 /org/freedesktop/DBus org.freedesktop.DBus.NameAcquired s
- :1.278
CAL :1.278(2)->org.bluez /org/bluez org.bluez.AgentManager1.RegisterAgent os
- /com/kevinisabelle/agent
- KeyboardDisplay
CAL :1.259(93)->org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.AddMatch s
- type='signal',sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0=':1.278'
RET org.freedesktop.DBus(28)->:1.259(93)
RET :1.259(94)->:1.278(2)
SIG :1.259(95)-> /org/bluez/hci0 org.freedesktop.DBus.Properties.PropertiesChanged sa{sv}as
- org.bluez.Adapter1
- Pairable: True
- []
CAL :1.278(3)->org.bluez /org/bluez org.bluez.AgentManager1.RequestDefaultAgent o
- /com/kevinisabelle/agent
RET :1.259(96)->:1.278(3)
CAL :1.278(4)->org.bluez /org/bluez/hci0 org.freedesktop.DBus.Properties.Set ssv
- org.bluez.Adapter1
- Powered
- True
RET :1.259(97)->:1.278(4)
CAL :1.278(5)->org.bluez /org/bluez/hci0 org.freedesktop.DBus.Properties.Set ssv
- org.bluez.Adapter1
- Discoverable
- True
RET :1.259(98)->:1.278(5)
CAL :1.278(6)->org.bluez /org/bluez/hci0 org.freedesktop.DBus.Properties.Set ssv
- org.bluez.Adapter1
- Pairable
- True
SIG :1.259(99)-> /org/bluez/hci0 org.freedesktop.DBus.Properties.PropertiesChanged sa{sv}as
- org.bluez.Adapter1
- Discoverable: True
- []
RET :1.259(100)->:1.278(6)
Подробнее здесь: https://stackoverflow.com/questions/794 ... net-and-tm
Bluetooth Bluez Agent, работающий нормально в Python, но не используя Dotnet и TMDS.DBUS ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Bluetooth Bluez Agent, работающий нормально в Python, но не используя Dotnet и TMDS.DBUS
Anonymous » » в форуме C# - 0 Ответы
- 23 Просмотры
-
Последнее сообщение Anonymous
-
-
-
QTDBUS, не получая сигналы от DBUS-SEND при использовании интерфейса QT DBUS XML
Anonymous » » в форуме C++ - 0 Ответы
- 3 Просмотры
-
Последнее сообщение Anonymous
-