dbus-native icon indicating copy to clipboard operation
dbus-native copied to clipboard

Set properties with dbus-native

Open zhangtianye opened this issue 10 years ago • 16 comments

Is there some ways for me to use your dbus-native to set a Property in dbus? And what's the signature of boolean? I want to set the property WirelessEnabled in org.freedesktop.NetworkManager,I want to set it to false or ture. Like the code:

var sysbus = require('dbus-native').systemBus();    
sysbus.invoke({
    path: '/org/freedesktop/NetworkManager',
    destination: 'org.freedesktop.NetworkManager',
    'interface': 'org.freedesktop.NetworkManager',
    member: 'SetPropertry',
    signature: '',     //what do I write here to set boolean?
    body: [
        'WirelessEnabled', [
            '',     //Boolean?
            [  //  Boolean?

            ]
        ]
    ],
    type: dbus.messageType.methodCall    //What do I write here?
}, function (err, res) {
    // etc...
});

What can I do? Thanks

zhangtianye avatar Apr 11 '15 09:04 zhangtianye

Documentation here: http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties

You need to use org.freedesktop.DBus.Properties as interface name, Set for member and interface name, property name + value as parameters

var sysbus = require('dbus-native').systemBus();    
sysbus.invoke({
    path: '/org/freedesktop/NetworkManager',
    destination: 'org.freedesktop.NetworkManager',
    interface: 'org.freedesktop.DBus.Properties',
    member: 'Set',
    signature: 'ssv', // string, string, variant
    body: [
       'org.freedesktop.NetworkManager',
       'WirelessEnabled',
        [ 'b', true ]  // variant, 'b' - signature, true - value
    ]
}); // type is "method call" by default in "invoke"

also see command line example using dbus-send here - http://cheesehead-techblog.blogspot.com.au/2012/09/dbus-tutorial-fun-with-network-manager.html

sidorares avatar Apr 11 '15 10:04 sidorares

When I got a connection, I found I can't use it directly in dbus,should I change the type from [{"type":"a","child":[{"type":"y","child":[]}]}] to 'ay'? And what's the type of [[{"type":"a","child":[{"type":"(","child":[{"type":"a","child":[{"type":"y","child":[]}]},{"type":"u","child":[]},{"type":"a","child":[{"type":"y","child":[]}]}]}]}] ? Is "a{ayuay" or some others?

zhangtianye avatar May 18 '15 07:05 zhangtianye

it's a(ayuay). There is "fromTree" function in signature.js - https://github.com/sidorares/node-dbus/blob/master/lib/signature.js#L60-L74 . You can use it to convert from parsed to a string representation. Code to convert your example (it was missing closing ], I added some newlines and indentation to make it more readable):

var t = [
  [
    {
      "type":"a",
      "child":[
        {
          "type":"(",
          "child":[
            {
              "type":"a",
              "child":[
                {
                  "type":"y",
                  "child":[]
                }
              ]
            },{
              "type":"u",
              "child":[]
            },{
              "type":"a",
              "child":[
                {
                  "type":"y",
                  "child":[]
                }]
            }
          ]
        }
      ]
    }
  ]
]

var ft = require('dbus-native/lib/signature.js').fromTree;
console.log(ft(t[0]));

sidorares avatar May 18 '15 07:05 sidorares

not quite sure what's in first question

sidorares avatar May 18 '15 07:05 sidorares

The first question is that I get a data-structure from dbus is: [["802-11-wireless",[["ssid",[[{"type":"a","child":[{"type":"y","child":[]}]}],[{"type":"Buffer","data":[67,77,67,67,45,90,75,89]}]]],["mode",[[{"type":"s","child":[]}],["infrastructure"]]],["mac-address",[[{"type":"a","child":[{"type":"y","child":[]}]}],[{"type":"Buffer","data":[20,117,144,246,114,233]}]]],["seen-bssids",[[{"type":"a","child":[{"type":"s","child":[]}]}],[["0A:19:70:00:31:83"]]]]]],["connection",[["id",[[{"type":"s","child":[]}],["CMCC-ZKY 2"]]],["uuid",[[{"type":"s","child":[]}],["7327670a-43ad-4982-96a7-b9265b86d32f"]]],["timestamp",[[{"type":"t","child":[]}],[1431934308]]],["type",[[{"type":"s","child":[]}],["802-11-wireless"]]]]],["ipv4",[["addresses",[[{"type":"a","child":[{"type":"a","child":[{"type":"u","child":[]}]}]}],[[]]]],["dns",[[{"type":"a","child":[{"type":"u","child":[]}]}],[[]]]],["method",[[{"type":"s","child":[]}],["auto"]]],["routes",[[{"type":"a","child":[{"type":"a","child":[{"type":"u","child":[]}]}]}],[[]]]]]],["ipv6",[["addresses",[[{"type":"a","child":[{"type":"(","child":[{"type":"a","child":[{"type":"y","child":[]}]},{"type":"u","child":[]},{"type":"a","child":[{"type":"y","child":[]}]}]}]}],[[]]]],["dns",[[{"type":"a","child":[{"type":"a","child":[{"type":"y","child":[]}]}]}],[[]]]],["method",[[{"type":"s","child":[]}],["auto"]]],["routes",[[{"type":"a","child":[{"type":"(","child":[{"type":"a","child":[{"type":"y","child":[]}]},{"type":"u","child":[]},{"type":"a","child":[{"type":"y","child":[]}]},{"type":"u","child":[]}]}]}],[[]]]]]]], I can't use it directly. Such as ssid in it, it is show as : ["ssid",[[{"type":"a","child":[{"type":"y","child":[]}]}],[{"type":"Buffer","data":[67,77,67,67,45,90,75,89]}]]],and I can only use it when I change it to: ['ssid', ['ay', [Ssid]]].Here is Ssid, Ssid = Buffer(JSON.parse(Ssid_Obj).data); It means that I can't use it like ['ssid', ['{"type":"a","child":[{"type":"y","child":[]}]}', [Ssid]]] or ['ssid', [{"type":"a","child":[{"type":"y","child":[]}]}, [Ssid]]].

zhangtianye avatar May 18 '15 07:05 zhangtianye

you have result of a{sv} type, and "v" comes as [ parsedSignatureTree, value ]. Sorry, I still trying to figure out what problem exactly you having

sidorares avatar May 18 '15 07:05 sidorares

I know that v is a value, I want to know Is the form of type can [{"type":"a","child":[{"type":"y","child":[]}]}] be used?

zhangtianye avatar May 18 '15 09:05 zhangtianye

So you want to set ay propriety?

sidorares avatar May 18 '15 10:05 sidorares

I want to send a connection to dbus,not set a property.

zhangtianye avatar May 19 '15 00:05 zhangtianye

"send a connection" - you want to ask NetworkManager to enable wireless connection, and to do that you want to set WirelessEnabled property of /org/freedesktop/NetworkManager service, org.freedesktop.NetworkManager object, org.freedesktop.NetworkManager interface?

sidorares avatar May 19 '15 00:05 sidorares

No,I use a dbus method, not a Property. I use the method AddAndActivateConnection,And the first parameter is a{sa{sv}}: connection ,see in https://developer.gnome.org/NetworkManager/0.9/spec.html, I Get a Setting form org.freedesktop.NetworkManager.Settings.Connection, see the object_path you need in d-feet , I find I can't use the connection directly with AddAndActivateConnection. It should be processing or treated.

zhangtianye avatar May 19 '15 02:05 zhangtianye

( googled some examples/documentatin for NM, this might be relevant: https://github.com/BenjaminHae/wifi-manager/blob/fdb39088a981e169f0eabe72cab9e6dd44a6d93d/network.py )

sidorares avatar May 19 '15 03:05 sidorares

Could you post the code you using to call AddAndActivateConnection and I try to help with parameters marshalling?

sidorares avatar May 19 '15 03:05 sidorares

Here is my code.In fact, if I only use AddAndActivateConnection in 'org.freedesktop.NetworkManager', I do not need to use treat so many data. I want to use update in 'org.freedesktop.NetworkManager.Settings.Connection' .And my error is in last few lines.

var DBus = require('dbus-native');
var dbus = new DBus.systemBus();

var loadInterface = function( obj_path, Interface, callback) {
    if( arguments.length != 3 ) {   
        throw Error;
    }else {
        var _NM_service_name = 'org.freedesktop.NetworkManager';
        var _systemBus = dbus;
        _systemBus.getService( _NM_service_name).getInterface(
        obj_path,
        Interface, function(err, NewInterface) {
            callback(err, NewInterface);
        });
    }
};


var setting = function(Set_obj, callback) {
    if( arguments.length != 2 ) {   
        throw Error;
    }else {
        var _obj = Set_obj;
        var _Interface = 'org.freedesktop.NetworkManager.Settings.Connection';
        loadInterface( _obj, _Interface, function( err, Setting_Con) {
            if(!err){
                if(Setting_Con.GetSettings){
                    var _GetSettings = Setting_Con.GetSettings
                    Setting_Con.GetSettings = function( callback){
                        _GetSettings(function(err, settings){
                            callback(err, settings);
                        });
                    };
                }

                if(Setting_Con.Update){
                    var _Update = Setting_Con.Update;
                    Setting_Con.Update = function( Con, callback) {
                        if( arguments.length != 2 ) {   
                            throw Error;
                        }else{
                            _Update( Con, function( err, result) {
                                callback( err, result);
                            });
                        }
                    };
                }


            }
            callback( err, Setting_Con);
        });
    }
};

var match = {
  '{' : '}',
  '(' : ')'
};

var ft = function(tree) {
  var res = '';
  for (var i=0; i < tree.length; ++i) {
    if (tree[i].child.length === 0)
      res += tree[i].type;
    else {
      if (tree[i].type === 'a') {
        res += 'a' + ft(tree[i].child);
      } else {
        res += tree[i].type + ft(tree[i].child) + match[tree[i].type];
      }
    }
  }
  return res;
}

var GetSettingConnection = function(settings){
    if( arguments.length != 1 ) {   
        throw new Error('received with' + arguments.length + '!    paramaters should work with 1');
    }else {
        var result = {};
        var my1 = [];
        var my2 = [];
        for(i = 0; i < settings.length; i++) {      
            result[settings[i][0]] = {};
            my2 = [];
            for(j = 0; j < settings[i][1].length; j++){
                result[settings[i][0]][settings[i][1][j][0]] = {};
                result[settings[i][0]][settings[i][1][j][0]]['type'] = ft(settings[i][1][j][1][0]);
                result[settings[i][0]][settings[i][1][j][0]]['data'] = settings[i][1][j][1][1][0];
                var ttt = [ settings[i][1][j][0],[ft(settings[i][1][j][1][0]),settings[i][1][j][1][1][0]] ] ;
                my2[j] = ttt;   
            }
            my1.push([settings[i][0],my2]);
        }
        return my1;
    }
};


setting('/org/freedesktop/NetworkManager/Settings/1',function(err, GetSetting){
    GetSetting.GetSettings(function(err, settings){
        console.log(JSON.stringify(settings));
        var set = GetSettingConnection(settings);
        console.log(JSON.stringify(set));
               /*if I don't use this Update function, It's no error.  And,nowether I use set or settings here, I got error. I want if I can, I need to use settings directly in this Update function.   
               */
        GetSetting.Update(set, function(err, result){      
            console.log(err, result);
        });

    });

});

zhangtianye avatar May 20 '15 02:05 zhangtianye

I was working on implementing read/write from a client to my service and ran into the same issue. It's frustrating to have the property set to 1234 and not even raise a NotImplementedError or similar let alone no documentation stating that setting values isn't supported.

Can we either update the documentation to state that we don't support setting values or figure out the ETA until it's added?

https://github.com/sidorares/node-dbus/blob/v0.2.0/lib/stdifaces.js#L118

twolfson avatar Jan 09 '16 07:01 twolfson

@twolfson agreed

It's relatively easy to add but until added I guess we should throw exception ( and have that explained in documentation )

( wow, that line looks ... well, that was probably the time when I just tried to figure out how dbus works )

sidorares avatar Jan 09 '16 08:01 sidorares