【问题标题】:`dasbus.error.DBusError: No valid service object found` from Bluez来自Bluez的`dasbus.error.DBusError:找不到有效的服务对象`
【发布时间】:2025-12-31 19:30:02
【问题描述】:

我已经没有关于如何调试这个的想法......我正在尝试在 Python 中实现蓝牙低功耗外设,并不断收到此错误:

dasbus.error.DBusError: No valid service object found

这是sudo dbus-monitor --system "destination='org.bluez'" "sender='org.bluez'" 上发生的事情

method call time=1638075250.607870 sender=:1.45928 -> destination=org.bluez serial=2 path=/org/bluez/hci0; interface=org.freedesktop.DBus.Introspectable; member=Introspect
method return time=1638075250.608574 sender=:1.5 -> destination=:1.45928 serial=1663 reply_serial=2
   string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="xml" type="s" direction="out"/>
</method></interface><interface name="org.bluez.Adapter1"><method name="StartDiscovery"></method><method name="SetDiscoveryFilter"><arg name="properties" type="a{sv}" direction="in"/>
</method><method name="StopDiscovery"></method><method name="RemoveDevice"><arg name="device" type="o" direction="in"/>
</method><method name="GetDiscoveryFilters"><arg name="filters" type="as" direction="out"/>
</method><property name="Address" type="s" access="read"></property><property name="AddressType" type="s" access="read"></property><property name="Name" type="s" access="read"></property><property name="Alias" type="s" access="readwrite"></property><property name="Class" type="u" access="read"></property><property name="Powered" type="b" access="readwrite"></property><property name="Discoverable" type="b" access="readwrite"></property><property name="DiscoverableTimeout" type="u" access="readwrite"></property><property name="Pairable" type="b" access="readwrite"></property><property name="PairableTimeout" type="u" access="readwrite"></property><property name="Discovering" type="b" access="read"></property><property name="UUIDs" type="as" access="read"></property><property name="Modalias" type="s" access="read"></property></interface><interface name="org.freedesktop.DBus.Properties"><method name="Get"><arg name="interface" type="s" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="value" type="v" direction="out"/>
</method><method name="Set"><arg name="interface" type="s" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="value" type="v" direction="in"/>
</method><method name="GetAll"><arg name="interface" type="s" direction="in"/>
<arg name="properties" type="a{sv}" direction="out"/>
</method><signal name="PropertiesChanged"><arg name="interface" type="s"/>
<arg name="changed_properties" type="a{sv}"/>
<arg name="invalidated_properties" type="as"/>
</signal>
</interface><interface name="org.bluez.GattManager1"><method name="RegisterApplication"><arg name="application" type="o" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
</method><method name="UnregisterApplication"><arg name="application" type="o" direction="in"/>
</method></interface><interface name="org.bluez.LEAdvertisingManager1"><method name="RegisterAdvertisement"><arg name="advertisement" type="o" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
</method><method name="UnregisterAdvertisement"><arg name="service" type="o" direction="in"/>
</method><property name="ActiveInstances" type="y" access="read"></property><property name="SupportedInstances" type="y" access="read"></property><property name="SupportedIncludes" type="as" access="read"></property></interface><interface name="org.bluez.Media1"><method name="RegisterEndpoint"><arg name="endpoint" type="o" direction="in"/>
<arg name="properties" type="a{sv}" direction="in"/>
</method><method name="UnregisterEndpoint"><arg name="endpoint" type="o" direction="in"/>
</method><method name="RegisterPlayer"><arg name="player" type="o" direction="in"/>
<arg name="properties" type="a{sv}" direction="in"/>
</method><method name="UnregisterPlayer"><arg name="player" type="o" direction="in"/>
</method></interface><interface name="org.bluez.NetworkServer1"><method name="Register"><arg name="uuid" type="s" direction="in"/>
<arg name="bridge" type="s" direction="in"/>
</method><method name="Unregister"><arg name="uuid" type="s" direction="in"/>
</method></interface></node>"
method call time=1638075250.617093 sender=:1.45928 -> destination=org.bluez serial=3 path=/org/bluez/hci0; interface=org.freedesktop.DBus.Properties; member=Set
   string "org.bluez.Adapter1"
   string "Powered"
   variant       boolean true
method return time=1638075250.617637 sender=:1.5 -> destination=:1.45928 serial=1664 reply_serial=3
method call time=1638075250.619644 sender=:1.45928 -> destination=org.bluez serial=4 path=/org/bluez/hci0; interface=org.freedesktop.DBus.Properties; member=Get
   string "org.bluez.Adapter1"
   string "Powered"
method return time=1638075250.620197 sender=:1.5 -> destination=:1.45928 serial=1665 reply_serial=4
   variant       boolean true
method call time=1638075250.627078 sender=:1.45928 -> destination=org.bluez serial=5 path=/org/bluez/hci0; interface=org.bluez.LEAdvertisingManager1; member=RegisterAdvertisement
   object path "/com/ah/Biofeedback/Advertisement/1"
   array [
   ]
method call time=1638075250.627809 sender=:1.5 -> destination=org.freedesktop.DBus serial=1666 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0=':1.45928'"
method return time=1638075250.627870 sender=org.freedesktop.DBus -> destination=:1.5 serial=1174 reply_serial=1666
method call time=1638075250.628483 sender=:1.5 -> destination=org.freedesktop.DBus serial=1667 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetNameOwner
   string ":1.45928"
method return time=1638075250.628534 sender=org.freedesktop.DBus -> destination=:1.5 serial=1175 reply_serial=1667
   string ":1.45928"
method call time=1638075250.628903 sender=:1.5 -> destination=org.freedesktop.DBus serial=1668 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Advertisement/1',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded'"
method return time=1638075250.628958 sender=org.freedesktop.DBus -> destination=:1.5 serial=1176 reply_serial=1668
method call time=1638075250.629497 sender=:1.5 -> destination=org.freedesktop.DBus serial=1669 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Advertisement/1',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved'"
method return time=1638075250.629572 sender=org.freedesktop.DBus -> destination=:1.5 serial=1177 reply_serial=1669
method call time=1638075250.629875 sender=:1.5 -> destination=org.freedesktop.DBus serial=1670 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.45928',path_namespace='/com/ah/Biofeedback/Advertisement/1'"
method return time=1638075250.629928 sender=org.freedesktop.DBus -> destination=:1.5 serial=1178 reply_serial=1670
method call time=1638075250.630459 sender=:1.5 -> destination=org.freedesktop.DBus serial=1671 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Advertisement/1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.bluez.LEAdvertisement1'"
method return time=1638075250.630517 sender=org.freedesktop.DBus -> destination=:1.5 serial=1179 reply_serial=1671
method call time=1638075250.631390 sender=:1.5 -> destination=org.freedesktop.DBus serial=1672 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=StartServiceByName
   string ":1.45928"
   uint32 0
error time=1638075250.631460 sender=org.freedesktop.DBus -> destination=:1.5 error_name=org.freedesktop.DBus.Error.ServiceUnknown reply_serial=1672
   string "The name :1.45928 was not provided by any .service files"
method call time=1638075250.631553 sender=:1.5 -> destination=:1.45928 serial=1673 path=/com/ah/Biofeedback/Advertisement/1; interface=org.freedesktop.DBus.ObjectManager; member=GetManagedObjects
error time=1638075250.632629 sender=:1.45928 -> destination=:1.5 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=1673
   string "No such interface “org.freedesktop.DBus.ObjectManager” on object at path /com/ah/Biofeedback/Advertisement/1"
method call time=1638075250.632916 sender=:1.5 -> destination=:1.45928 serial=1674 path=/com/ah/Biofeedback/Advertisement/1; interface=org.freedesktop.DBus.Properties; member=GetAll
   string "org.bluez.LEAdvertisement1"
method return time=1638075250.639601 sender=:1.45928 -> destination=:1.5 serial=7 reply_serial=1674
   array [
      dict entry(
         string "Appearance"
         variant             uint16 768
      )
      dict entry(
         string "Discoverable"
         variant             boolean true
      )
      dict entry(
         string "DiscoverableTimeout"
         variant             uint16 10000
      )
      dict entry(
         string "LocalName"
         variant             string "AH Biofeedback Device"
      )
      dict entry(
         string "ServiceUUIDS"
         variant             array [
               string "what"
            ]
      )
      dict entry(
         string "Type"
         variant             string "peripheral"
      )
   ]
signal time=1638075250.641071 sender=:1.5 -> destination=(null destination) serial=1675 path=/org/bluez/hci0; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
   string "org.bluez.LEAdvertisingManager1"
   array [
      dict entry(
         string "SupportedInstances"
         variant             byte 4
      )
      dict entry(
         string "ActiveInstances"
         variant             byte 1
      )
   ]
   array [
   ]
method return time=1638075250.641346 sender=:1.5 -> destination=:1.45928 serial=1676 reply_serial=5
method call time=1638075250.649537 sender=:1.45928 -> destination=org.bluez serial=8 path=/org/bluez/hci0; interface=org.bluez.GattManager1; member=RegisterApplication
   object path "/com/ah/Biofeedback/Application/1"
   array [
   ]
method call time=1638075250.649994 sender=:1.5 -> destination=org.freedesktop.DBus serial=1677 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetNameOwner
   string ":1.45928"
method return time=1638075250.650051 sender=org.freedesktop.DBus -> destination=:1.5 serial=1181 reply_serial=1677
   string ":1.45928"
method call time=1638075250.650459 sender=:1.5 -> destination=org.freedesktop.DBus serial=1678 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Application/1',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded'"
method return time=1638075250.650515 sender=org.freedesktop.DBus -> destination=:1.5 serial=1182 reply_serial=1678
method call time=1638075250.651102 sender=:1.5 -> destination=org.freedesktop.DBus serial=1679 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Application/1',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved'"
method return time=1638075250.651159 sender=org.freedesktop.DBus -> destination=:1.5 serial=1183 reply_serial=1679
method call time=1638075250.651590 sender=:1.5 -> destination=org.freedesktop.DBus serial=1680 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.45928',path_namespace='/com/ah/Biofeedback/Application/1'"
method return time=1638075250.651646 sender=org.freedesktop.DBus -> destination=:1.5 serial=1184 reply_serial=1680
method call time=1638075250.651759 sender=:1.5 -> destination=:1.45928 serial=1681 path=/com/ah/Biofeedback/Application/1; interface=org.freedesktop.DBus.ObjectManager; member=GetManagedObjects
method return time=1638075250.659644 sender=:1.45928 -> destination=:1.5 serial=9 reply_serial=1681
   array [
      dict entry(
         object path "/com/ah/Biofeedback/Service/1"
         array [
            dict entry(
               string "org.bluez.GattService1"
               array [
                  dict entry(
                     string "UUID"
                     variant                         string "service-uuid-abc"
                  )
                  dict entry(
                     string "Primary"
                     variant                         boolean true
                  )
                  dict entry(
                     string "Characteristics"
                     variant                         array [
                           object path "/com/ah/Biofeedback/Characteristic/1"
                        ]
                  )
               ]
            )
         ]
      )
      dict entry(
         object path "/com/ah/Biofeedback/Characteristic/1"
         array [
            dict entry(
               string "org.bluez.GattCharacteristic1"
               array [
                  dict entry(
                     string "Service"
                     variant                         object path "/com/ah/Biofeedback/Service/1"
                  )
                  dict entry(
                     string "UUID"
                     variant                         string "characteristic-uuid-abc"
                  )
                  dict entry(
                     string "Flags"
                     variant                         array [
                             string "broadcast"
                        ]
                  )
                  dict entry(
                     string "Descriptors"
                     variant                         array [
                        ]
                  )
               ]
            )
         ]
      )
   ]
method call time=1638075250.660665 sender=:1.5 -> destination=org.freedesktop.DBus serial=1682 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Service/1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.bluez.GattService1'"
method return time=1638075250.660724 sender=org.freedesktop.DBus -> destination=:1.5 serial=1185 reply_serial=1682
method call time=1638075250.663350 sender=:1.5 -> destination=org.freedesktop.DBus serial=1683 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Characteristic/1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.bluez.GattCharacteristic1'"
method return time=1638075250.663436 sender=org.freedesktop.DBus -> destination=:1.5 serial=1186 reply_serial=1683
error time=1638075250.663466 sender=:1.5 -> destination=:1.45928 error_name=org.bluez.Error.Failed reply_serial=8
   string "No valid service object found"
method call time=1638075250.663509 sender=:1.5 -> destination=org.freedesktop.DBus serial=1685 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RemoveMatch
   string "type='signal',sender=':1.45928',path_namespace='/com/ah/Biofeedback/Application/1'"
method return time=1638075250.663556 sender=org.freedesktop.DBus -> destination=:1.5 serial=1187 reply_serial=1685
method call time=1638075250.663584 sender=:1.5 -> destination=org.freedesktop.DBus serial=1686 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RemoveMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Service/1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.bluez.GattService1'"
method return time=1638075250.663634 sender=org.freedesktop.DBus -> destination=:1.5 serial=1188 reply_serial=1686
method call time=1638075250.663663 sender=:1.5 -> destination=org.freedesktop.DBus serial=1687 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RemoveMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Characteristic/1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.bluez.GattCharacteristic1'"
method return time=1638075250.663712 sender=org.freedesktop.DBus -> destination=:1.5 serial=1189 reply_serial=1687
method call time=1638075250.663827 sender=:1.5 -> destination=org.freedesktop.DBus serial=1688 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RemoveMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Application/1',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded'"
method return time=1638075250.663880 sender=org.freedesktop.DBus -> destination=:1.5 serial=1190 reply_serial=1688
method call time=1638075250.664064 sender=:1.5 -> destination=org.freedesktop.DBus serial=1689 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RemoveMatch
   string "type='signal',sender=':1.45928',path='/com/ah/Biofeedback/Application/1',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved'"
method return time=1638075250.664119 sender=org.freedesktop.DBus -> destination=:1.5 serial=1191 reply_serial=1689

这是我的代码:

from dasbus.connection       import SystemMessageBus
from dasbus.typing           import *
from dasbus.server.interface import dbus_interface
from dasbus.server.interface import dbus_signal

from dasbus.server.publishable import Publishable
from dasbus.server.template    import InterfaceTemplate

from dasbus.loop             import EventLoop
from threading               import Thread


@dbus_interface("org.bluez.LEAdvertisement1")
class BiofeedackAdvertisement(object):

    def Release(self) -> None:
        print("released")

    @property
    def Type(self) -> Str:
        return "peripheral"

    @property
    def ServiceUUIDS(self) -> List[Str]:
        return ["what"]

    @property
    def Discoverable(self) -> Bool:
        return True

    @property
    def DiscoverableTimeout(self) -> UInt16:
        return 10000

    @property
    def LocalName(self) -> Str:
        return "AH Biofeedback Device"

    # https://specificationrefs.bluetooth.com/assigned-values/Appearance%20Values.pdf
    @property
    def Appearance(self) -> UInt16:
        return 768 # Thermometer

# path: "/com/ah/Biofeedback/Application/1"
class Application(Publishable):
    def for_publication(self):
        return ApplicationInterface(self)

@dbus_interface("org.bluez.GattApplication1")
class ApplicationGattInterface(InterfaceTemplate):
    pass

@dbus_interface("org.freedesktop.DBus.ObjectManager")
class ApplicationInterface(ApplicationGattInterface):

    def GetManagedObjects(self) -> Dict[ObjPath, Dict[Str, Dict[Str, Variant]]]:
        return {
            "/com/ah/Biofeedback/Service/1":    ServiceInterface(Service()).get_properties(),
            "/com/ah/Biofeedback/Characteristic/1":         CharacteristicInterface(Characteristic()).get_properties(),
#            "/com/ah/Biofeedback/Descriptor/1": Descriptor().get_properties(),
        }

class Service(Publishable):
    def for_publication(self):
        return ServiceInterface(self)

# Not sure if this is being used, but it's not the problem right now.
@dbus_interface("org.freedesktop.DBus.Properties")
class ServiceInterfaceProperties(InterfaceTemplate):

    @dbus_signal
    def PropertiesChanged(self, interface: Str, changed_properties: Dict[Str, Variant], invalidated_properties: List[Str]):
        print("PROPS CHANGED")
        pass

    def GetAll(self, interface: Str) -> Dict[Str, Variant]: 
        print("GETALL")
        return self.get_properties()["org.bluez.GattService1"]


@dbus_interface("org.bluez.GattService1")
class ServiceInterfaceGatt(InterfaceTemplate):

    @property
    def UUID(self) -> Str:
        return "service-uuid-abc"

    @property
    def Primary(self) -> Bool:
        return True

# path: /com/ah/Biofeedback/Service/1
class ServiceInterface(ServiceInterfaceGatt, ServiceInterfaceProperties):

    _UUID = Variant("s", "service-uuid-abc")

    def get_properties(self):
        return {
            "org.bluez.GattService1": {
                "UUID": self._UUID,
                "Primary": Variant("b", True),
                "Characteristics": Variant.new_array(None, [Variant("o", "/com/ah/Biofeedback/Characteristic/1")]),
            }
        }

class Characteristic(Publishable):
    def for_publication(self):
        return CharacteristicInterface(self)

@dbus_interface("org.bluez.GattCharacteristic1")
class CharacteristicInterfaceGatt(InterfaceTemplate):
    
    def ReadValue(self, options: Dict[Str, Str]) -> List[Byte]:
        print("TRIED TO READ VALUE")
        return [0xDEAD]

    def WriteValue(self, value: List[Byte], options: Dict[Str, Str]) -> None:
        print("TRIED TO WRITE VALUE")
        pass

    @property
    def UUID(self) -> Str:
        return "characteristic-uuid-abc"

    @property
    def Service(self) -> ObjPath:
        return "/com/ah/Biofeedback/Service/1"
    

# path: /com/ah/Biofeedback/Characteristic/1
class CharacteristicInterface(CharacteristicInterfaceGatt):
    _UUID = Variant("s", "characteristic-uuid-abc")

    def get_properties(self):
        return {
            "org.bluez.GattCharacteristic1": {
                "Service": Variant("s", "/com/ah/Biofeedback/Service/1"),
                "UUID": self._UUID,
                "Flags": Variant.new_array(None, [Variant("s", "broadcast")]),
                #"Descriptors": Variant.new_array(None, [Variant("o", "/com/ah/Biofeedback/Descriptor/1")]),
                "Descriptors": Variant.new_array(VariantType("t"), []),
            }
        }

# path: /com/ah/Biofeedback/Descriptor/1
# @dbus_interface("org.bluez.GattDescriptor1")
class Descriptor(object):
    _UUID = Variant("s", "descriptor-uuid-1vc")

    def get_properties(self):
        return {
            "org.bluez.GattDescriptor1": {
                "Characteristic": Variant("s", "/com/ah/Biofeedback/Characteristic/1"),
                "UUID": self._UUID,
                "Flags": Variant.new_array(VariantType("t"), []),
            }
        }

def main():

    bus = SystemMessageBus()
    Thread(target=EventLoop().run).start()
    bus.register_service("com.ah.Biofeedback")

    proxy = bus.get_proxy("org.bluez", "/org/bluez/hci0")

    proxy.Set("org.bluez.Adapter1", "Powered", Variant("b", True))
    print(proxy.Get("org.bluez.Adapter1", "Powered"))

    advertisementPath = "/com/ah/Biofeedback/Advertisement/1"
    bus.publish_object(advertisementPath, BiofeedackAdvertisement())
    proxy.RegisterAdvertisement(advertisementPath, {})

    bus.publish_object("/com/ah/Biofeedback/Service/1", Service().for_publication())
    bus.publish_object("/com/ah/Biofeedback/Characteristic/1", Characteristic().for_publication())

    appPath = "/com/ah/Biofeedback/Application/1"
    bus.publish_object(appPath, Application().for_publication())
    proxy.RegisterApplication(appPath, {})

if __name__ == '__main__':
    main()

看起来Service 已在总线上注册:

sudo dbus-send --system --print-reply   \
>   --dest=:1.46935                       \
>   /com/ah/Biofeedback/Service/1  \
>   org.freedesktop.DBus.Introspectable.Introspect

method return time=1638120479.547238 sender=:1.13051 -> destination=:1.13060 serial=12 reply_serial=2
   string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
                      "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.58.3 -->
<node>
  <interface name="org.freedesktop.DBus.Properties">
    <method name="Get">
      <arg type="s" name="interface_name" direction="in"/>
      <arg type="s" name="property_name" direction="in"/>
      <arg type="v" name="value" direction="out"/>
    </method>
    <method name="GetAll">
      <arg type="s" name="interface_name" direction="in"/>
      <arg type="a{sv}" name="properties" direction="out"/>
    </method>
    <method name="Set">
      <arg type="s" name="interface_name" direction="in"/>
      <arg type="s" name="property_name" direction="in"/>
      <arg type="v" name="value" direction="in"/>
    </method>
    <signal name="PropertiesChanged">
      <arg type="s" name="interface_name"/>
      <arg type="a{sv}" name="changed_properties"/>
      <arg type="as" name="invalidated_properties"/>
    </signal>
  </interface>
  <interface name="org.freedesktop.DBus.Introspectable">
    <method name="Introspect">
      <arg type="s" name="xml_data" direction="out"/>
    </method>
  </interface>
  <interface name="org.freedesktop.DBus.Peer">
    <method name="Ping"/>
    <method name="GetMachineId">
      <arg type="s" name="machine_uuid" direction="out"/>
    </method>
  </interface>
  <interface name="org.bluez.GattService1">
    <property type="b" name="Primary" access="read">
    </property>
    <property type="s" name="UUID" access="read">
    </property>
  </interface>
</node>
"

/var/log/syslog 提供一点线索:

bluetoothd[22894]: Failed to read "UUID" property of service
bluetoothd[22894]: Failed to add service
bluetoothd[22894]: Failed to create GATT service entry in local database

依赖项设置起来很麻烦,所以这里有一个 docker 容器:

docker run -it --rm \
  --privileged \
  --workdir /app \
  --volume "$PWD":/app \
  --volume /var/run/dbus/:/var/run/dbus/:z \
soodesune/python3-bluetooth dbus-bluetooth.py

我还能做些什么来调试这个错误?如何找出我的 Service UUID 有什么问题?

【问题讨论】:

    标签: bluetooth-lowenergy dbus bluez


    【解决方案1】:

    想通了!我必须解决一长串小问题。这是我调试的过程:

    • 运行 sudo dbus-monitor --system "destination='org.bluez'" "sender='org.bluez'" 以查看 Bluez 从 dbus 发送/接收的内容
    • 观看 /var/log/syslog 以查看 Bluez 正在记录哪些错误,但 /not/ 正在发送到 dbus
    • 下载您的Bluez版本的源代码
    • 运行你的程序

    然后:

    • 确保 dbus 上的流量看起来正确
    • 当您在 /var/log/syslog 中看到错误时,请使用 grep 查找错误的源代码,看看哪里出了问题。大多数时候,我不满意类型检查逻辑。例如:UUID 有一些非常具体的检查,我有一些 Object Path 类型被错误编码为 String

    继续循环执行这些步骤,直到您完成工作为止。

    我写了一篇关于使用Bluetooth, D-Bus, BlueZ on a Raspberry Pi at raspberrypi-bluetooth.com的文章

    【讨论】: