dbusjs / node-dbus-next

🚌 The next great dbus library for node
https://www.npmjs.com/package/dbus-next
155 stars 52 forks source link

Unable to serialize a{sa{sv}} #105

Closed ostollmann closed 2 years ago

ostollmann commented 2 years ago

I am trying to call NetworkManager's AddAndActivateConnection2 method which takes an a{sa{sv}} argument. I create it as follows:

  const s = new Variant('a{sa{sv}}', {
    connection: new Variant('a{sv}', {
      id: new Variant('s', 'plc-ethernet'),
      type: new Variant('s', 'ethernet'),
      'interface-name': new Variant('s', 'iface'),
    }),
    ipv4: new Variant('a{sv}', {
      'address-data': new Variant('aa{sv}', [
        {
          address: '192.168.0.140',
          prefix: '255.255.255.0',
        },
      ]),
      gateway: new Variant('s', '192.168.0.1'),
      method: new Variant('s', 'manual'),
    }),
    ipv6: new Variant('a{sv}', {
      method: new Variant('s', 'disabled'),
    }),
  })

Unfortunately, I get the following error (I also tried making the top-level Variant a{sv} but I also get an error):

/app/node_modules/dbus-next/lib/marshall-compat.js:111
        throw new Error(`expecting an object for signature '${signatureStr}' (got ${typeof value})`);
              ^

Error: expecting an object for signature 'a{sa{sv}}' (got object)
    at jsToMarshalFmt (/app/node_modules/dbus-next/lib/marshall-compat.js:111:15)
    at marshallMessage (/app/node_modules/dbus-next/lib/marshall-compat.js:179:27)
    at EventEmitter.self.message (/app/node_modules/dbus-next/lib/connection.js:164:27)
    at /app/node_modules/dbus-next/lib/bus.js:349:24
    at new Promise (<anonymous>)
    at MessageBus.call (/app/node_modules/dbus-next/lib/bus.js:326:12)
    at /app/node_modules/dbus-next/lib/client/proxy-object.js:181:16
    at new Promise (<anonymous>)
    at ProxyObject._callMethod (/app/node_modules/dbus-next/lib/client/proxy-object.js:169:12)
    at ProxyInterface.iface.<computed> [as AddAndActivateConnection2] (/app/node_modules/dbus-next/lib/client/proxy-interface.js:218:37)

Any idea what may be going wrong? Note that I am not using the Interface class, or so, just plain calling the method on the interface:

  manager.getInterface('org.freedesktop.NetworkManager').AddAndActivateConnection2(s, devicePath, '/', o)
acrisci commented 2 years ago

I believe you're passing the toplevel object as a Variant when it should be a simple object. Try this:

  const s = {
    connection: new Variant('a{sv}', {
      id: new Variant('s', 'plc-ethernet'),
      type: new Variant('s', 'ethernet'),
      'interface-name': new Variant('s', 'iface'),
    }),
    ipv4: new Variant('a{sv}', {
      'address-data': new Variant('aa{sv}', [
        {
          address: '192.168.0.140',
          prefix: '255.255.255.0',
        },
      ]),
      gateway: new Variant('s', '192.168.0.1'),
      method: new Variant('s', 'manual'),
    }),
    ipv6: new Variant('a{sv}', {
      method: new Variant('s', 'disabled'),
    }),
  }
ostollmann commented 2 years ago

Thank you @acrisci! I finally got it to work as follows:

{
  connection: {
    id: new Variant('s', name),
    type: new Variant('s', 'ethernet'),
    'interface-name': new Variant('s', iface),
  },
  ipv4: {
    'address-data': new Variant('aa{sv}', [
      {
        address: new Variant('s', ipAddr),
        prefix: new Variant('u', ipPrefix),
      },
    ]),
    gateway: new Variant('s', gateway),
    method: new Variant('s', 'manual'),
  },
  ipv6: {
    method: new Variant('s', 'disabled'),
  },
}