sidorares/dbus-native

firefly linux node 8.9.4 example fails unknown bus address

dronesalot opened this issue · 13 comments

I'm trying to get the module to run on a small embedded device. I've installed it as per instructions. I took the example below directly from the README.

var dbus = require('dbus-native');
var sessionBus = dbus.sessionBus();
sessionBus.getService('org.freedesktop.Notifications').getInterface(
'/org/freedesktop/Notifications',
'org.freedesktop.Notifications', function(err, notifications) {

// dbus signals are EventEmitter events
notifications.on('ActionInvoked', function() {
    console.log('ActionInvoked', arguments);
});
notifications.on('NotificationClosed', function() {
    console.log('NotificationClosed', arguments);
});
notifications.Notify('exampl', 0, '', 'summary 3', 'new message text', ['xxx yyy', 'test2', 'test3', 'test4'], [],  5, function(err, id) {
   //setTimeout(function() { n.CloseNotification(id, console.log); }, 4000);
});

});

It fails with the following error:

/home/miker/test1/node_modules/dbus-native/index.js:22
if (!busAddress) throw new Error('unknown bus address');
^

Error: unknown bus address
at createStream (/home/miker/test1/node_modules/dbus-native/index.js:22:26)
at createConnection (/home/miker/test1/node_modules/dbus-native/index.js:76:31)
at Object.module.exports.createClient (/home/miker/test1/node_modules/dbus-native/index.js:136:20)
at Object.module.exports.sessionBus (/home/miker/test1/node_modules/dbus-native/index.js:149:25)
at Object. (/home/miker/test1/test.js:2:23)
at Module._compile (module.js:643:30)
at Object.Module._extensions..js (module.js:654:10)
at Module.load (module.js:556:32)
at tryModuleLoad (module.js:499:12)
at Function.Module._load (module.js:491:3)
miker@firefly:/test1$ node -v
v8.9.4
miker@firefly:
/test1$ npm -v
6.0.0

sessionBus() is a shortcut for "give me a client connected to address pointed by DBUS_SESSION_BUS_ADDRESS env variable", and in your case it's probably not set. Usually it's dbus-launch job to set it correctly, you neet to check who is launching dbus-daemon and maybe set DBUS_SESSION_BUS_ADDRESS manually if it's not set

I think you're correct, as I was running it from a shell and it appears to work when run in an xterm. One thing I wish for is better errors, or a troubleshooting type doc to help in these matters. I've spent the better part of the day trying to get notification of a USB mount event and I'm only slightly closer to a resolution.

One thing I wish for is better errors, or a troubleshooting type doc

Yes, fully agree with you. This is something that definitely needs improvement

@sidorares I'm working on the udisk2 interface. Really, I just need to have a function called when a USB stick is inserted and the system mounts it (using automount).

Using dbus-monitor I can see the following message for the insertion:

signal time=1525065825.986584 sender=:1.59 -> destination=(null destination) serial=2187 path=/org/freedesktop/UDisks2; interface=org.freedesktop.DBus.ObjectManager; member=InterfacesAdded
   object path "/org/freedesktop/UDisks2/block_devices/sdb1"
   array [
      dict entry(
         string "org.freedesktop.UDisks2.Block"
         array [
            dict entry(
               string "Device"
               variant                   array of bytes "/dev/sdb1" + \0
            )
            dict entry(
               string "PreferredDevice"
               variant                   array of bytes "/dev/sdb1" + \0
            )
            dict entry(
               string "Symlinks"
               variant                   array [
                     array of bytes "/dev/disk/by-id/usb-Lexar_microSD_RDR_000000000001-0:0-part1" + \0
                     array of bytes "/dev/disk/by-path/platform-xhci-hcd.9.auto-usb-0:1.1.3:1.0-scsi-0:0:0:0-part1" + \0
                     array of bytes "/dev/disk/by-uuid/3A60-044B" + \0
[SNIP]

When the filesystem mount starts I see this:

signal time=1525065831.741319 sender=:1.59 -> destination=(null destination) serial=2190 path=/org/freedesktop/UDisks2; interface=org.freedesktop.DBus.ObjectManager; member=InterfacesAdded
object path "/org/freedesktop/UDisks2/jobs/206"
array [
dict entry(
string "org.freedesktop.UDisks2.Job"
array [
dict entry(
string "Operation"
variant string "filesystem-mount"
)
dict entry(
string "Progress"
variant double 0
)
[SNIP]

As job 206 runs, I see the mount point show up and the job completes.

signal time=1525065831.775012 sender=:1.59 -> destination=(null destination) serial=2191 path=/org/freedesktop/UDisks2/block_devices/sdb1; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
string "org.freedesktop.UDisks2.Filesystem"
array [
dict entry(
string "MountPoints"
variant array [
array of bytes "/media/miker/3A60-044B" + \0
]
)
]
array [
]
signal time=1525065831.798591 sender=:1.59 -> destination=(null destination) serial=2192 path=/org/freedesktop/UDisks2/jobs/206; interface=org.freedesktop.UDisks2.Job; member=Completed
boolean true
string ""

The trouble is, I can't figure out how to get the contents of these through dbus-native. I've messed with the code for a good 6 hours and every way I've tried to call GetAll it either dies with an exception or just returns an undefined var. Can you give me any pointers?

thanks

As these are all signal the easiest way is just to listen all messages and check if message is from service

var dbus = require('dbus-native');
var conn = dbus.createConnection();
conn.on('message', function(msg) { 
  if (msg.path === '/org/freedesktop/UDisks2' && msg.member === 'InterfacesAdded' ) {
     console.log('Interface added: ', msg.body);
  } 
});

Not sure why, but that code does not seem to fire at all. Adding debugging in there shows it never runs. Any ideas?

var conn = dbus.createConnection();
conn.on('message', function(msg) {
console.log("Incoming: ",msg);
if (msg.path === '/org/freedesktop/UDisks2' && msg.member === 'InterfacesAdded' ) {
console.log('Interface added: ', msg.body);
}
});

I'll try to test this code in couple of hours when I beck home at my desktop computer

This morning I tried a variety of things but the conn never seems to fire with messages. I'm not sure if it's a permissions thing or something else failing silently.

@sidorares I put another 5-6h of work into it. Still not getting anywhere. I wonder if you tested the script on your side? If it worked there, is there anything permissions-wise that could be interfering?

so my example is definitely not enough. In order to receive signals client must send AddMatch message first

try this to see listen for all events:

var dbus = require('dbus-native');
var bus = dbus.sessionBus();
bus.connection.on('message', console.log);
bus.addMatch("type='signal'");
bus.addMatch("type='method_call'");
bus.addMatch("type='method_return'");
bus.connection.on('message', function(msg) {
  console.log(msg);
});

Thanks, the addMatch part really made a difference!

Is there anything documented on how to manage the msg object?

Message is plain object, to better understand semantics of what's there best start is dbus spec: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages

Also if you want to continue with "low level" approach (not via automatic introspection) section on match rules also useful: https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules

I didn't know where to find the session bus address at first. This worked for me on Arch linux:
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus node index.js