0

I'm pretty much following the example on https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/GDBusProxy.html in order to set up Connman signal callbacks on dbus, however in my callback function:

g_signal_connect(
        this->manager_proxy,
        "property-changed",
        G_CALLBACK(on_manager_properties_changed),
        this); //Pass in pointer to self so static function can operate on object.
g_signal_connect(
        this->manager_proxy,
        "technology-added",
        G_CALLBACK(on_manager_tech_added),
        this); //Pass in pointer to self so static function can operate on object.
g_signal_connect(
        this->manager_proxy,
        "technology-removed",
        G_CALLBACK(on_manager_tech_removed),
        this); //Pass in pointer to self so static function can operate on object

void
CM_InterfaceController::on_manager_properties_changed (
                       GDBusProxy          *proxy,
                       GVariant            *changed_properties,
                       const gchar* const  *invalidated_properties,
                       gpointer             user_data)
{
    if(!user_data){CM_ERR("NO THIS * on_manager_properties_changed");return;}
    CM_InterfaceController * ths = static_cast<CM_InterfaceController *>(user_data);
    std::cout<<"on_manager_properties_changed"<<std::endl;
    if(changed_properties){
        std::cout<<"children: "<<g_variant_n_children(changed_properties)<<std::endl;
    }    
}

The number of children I am told the GVariant * object contains is completely wrong. For instance, my feedback:

Calling Extraction
Service List Size: 1
Identified Ethernet Link: 
Path: /net/connman/service/ethernet_0800277d326e_cable
        Type: ethernet
        Sate: ready
        Favorite: 0
        Auto Connect: 0
        Name: Wired
        Net Mode: manual
        Iface: eth0
        Mac: 08:00:27:7D:32:6E
        IP Address: 10.0.2.15
        Net Mask: 255.255.255.0
on_manager_properties_changed
children: 139764141513856
on_manager_properties_changed
children: 145

on_manager_properties_changed children: 139764141513856 on_manager_properties_changed children: 145

Both of those values are way out of the ballpark, one more significantly than the other. Even more, if I try to parsed the values out of the GVariant object, I end up seg faulting even just by trying to call g_variant_get_type_string. Why on earth is my callback returning with a garbage data pointer? Seems like if it has nothing it should at least return a null pointer.

edit: Source Code https://drive.google.com/file/d/1E0Kg9JKW54gghUHbVyBJ0ysBIdqBlpVA/view?usp=sharing

And some of the dbus-monitor --system output:

signal time=1549641357.679460 sender=:1.3 -> destination=(null destination) serial=488 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
   string "State"
   variant       string "ready"
signal time=1549641357.680844 sender=:1.3 -> destination=(null destination) serial=489 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
   string "Nameservers"
   variant       array [
         string "10.0.2.3"
      ]
signal time=1549641357.681186 sender=:1.3 -> destination=(null destination) serial=490 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
   string "Domains"
   variant       array [
      ]
signal time=1549641357.681601 sender=:1.3 -> destination=(null destination) serial=491 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
   string "Proxy"
   variant       array [
         dict entry(
            string "Method"
            variant                string "direct"
         )
      ]
signal time=1549641357.681780 sender=:1.3 -> destination=(null destination) serial=492 path=/net/connman/technology/ethernet; interface=net.connman.Technology; member=PropertyChanged
   string "Connected"
   variant       boolean true
signal time=1549641357.682210 sender=:1.3 -> destination=(null destination) serial=493 path=/; interface=net.connman.Manager; member=PropertyChanged
   string "State"
   variant       string "ready"
signal time=1549641357.696004 sender=:1.3 -> destination=(null destination) serial=494 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
   string "IPv4"
   variant       array [
         dict entry(
            string "Method"
            variant                string "dhcp"
         )
      ]
signal time=1549641357.696227 sender=:1.3 -> destination=(null destination) serial=495 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
   string "IPv4"
   variant       array [
         dict entry(
            string "Method"
            variant                string "dhcp"
         )
         dict entry(
            string "Address"
            variant                string "10.0.2.15"
         )
         dict entry(
            string "Netmask"
            variant                string "255.255.255.0"
         )
      ]
signal time=1549641357.696454 sender=:1.3 -> destination=(null destination) serial=496 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
   string "IPv4"
   variant       array [
         dict entry(
            string "Method"
            variant                string "dhcp"
         )
         dict entry(
            string "Address"
            variant                string "10.0.2.15"
         )
         dict entry(
            string "Netmask"
            variant                string "255.255.255.0"
         )
         dict entry(
            string "Gateway"
            variant                string "10.0.2.2"
         )
      ]

Capture of object in memory

Tyler Cox
  • 117
  • 1
  • 10
  • So my current theory is that there are certain elements of my XML file used to generate the source gdbus code from gdbus-codegen. I just did an introspect of my net.connman service and there are some subtle differences between the introspect it gave me vs the xml file I am currently using. It appears the PropertyChanged signals are both the same though, so that doesn't make me fee super close to solving this, but maybe it is causing issues in the background somehow. – Tyler Cox Feb 08 '19 at 17:35
  • Tried re-doing introspect on net.connman and then re-running gdbus-codegen and it didn't fix it. – Tyler Cox Feb 08 '19 at 17:54
  • I think it may have something to do with the signal initializer in the generated code being return type G_TYPE_NONE: g_signal_new ("property-changed", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (connmanManagerIface, property_changed), NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VARIANT); – Tyler Cox Feb 08 '19 at 18:34
  • If I try running: connman_manager_emit_property_changed(this->manager_proxy,"test",g_variant_new_variant(g_variant_new_string("value"))); It also fails, just to test if there is nothing odd with the dbus data. – Tyler Cox Feb 08 '19 at 19:36

1 Answers1

1

FIGURED IT OUT!

In my XML file the signal I am watching for is:

  <signal name="PropertyChanged">
     <arg name="name" type="s" />
     <arg name="value" type="v" />
  </signal>

And as much as I am trying to figure out why the example callback function on freedesktop.org is in reverse I had to modify the following:

static void on_manager_properties_changed (
                       GDBusProxy          *proxy,
                       GVariant            *changed_properties,
                       const gchar* const  *invalidated_properties,
                       gpointer             user_data);

to:

static void on_manager_properties_changed (
                       GDBusProxy          *proxy,
                       const gchar* const  *invalidated_properties, //(name)
                       GVariant            *changed_properties, //(value)
                       gpointer             user_data);

So that the type='s' came before the type='v' in the callback function. After that, everything was good. I think maybe whatever signal freedesktop's example was watching, might have been a different element of information than what I was going for.

Tyler Cox
  • 117
  • 1
  • 10
  • 1
    For background: the two methods of property notification look similar but are really implemented completely differently. `PropertyChanged` is an actual part of the Connman D-Bus API -- this is needed because Connman does not support actual D-Bus properties at all (for historical reasons IIRC). The example code you linked to uses `GDBusProxy::g-properties-changed` which does use D-Bus properties. – Jussi Kukkonen Feb 09 '19 at 10:32