August 9, 2011

TheQtGuy TheQtGuy
Lab Rat
2 posts

Change from HAL to udisk

 

Hello everyone,

I’m developing a program that should detect whenever a USB storage device is plugged/unplugged. After extensive search I’ve found an example that worked ok for me:

  1. QDBusConnection::systemBus().connect(
  2.                          "org.freedesktop.Hal",
  3.                          "/org/freedesktop/Hal/Manager",
  4.                          "org.freedesktop.Hal.Manager",
  5.                          "DeviceAdded",
  6.                          this, SLOT(deviceAdded());
  7. QDBusConnection::systemBus().connect(
  8.                          "org.freedesktop.Hal",
  9.                          "/org/freedesktop/Hal/Manager",
  10.                          "org.freedesktop.Hal.Manager",
  11.                          "DeviceRemoved",
  12.                          this, SLOT(deviceRemoved());
  13.  
  14. void deviceAdded(){
  15.                          qDebug() << "device added!";
  16. }
  17.  
  18. void deviceRemoved(){
  19.                          qDebug() << "device removed!";
  20. }

However, reading more about HAL I’ve discovered that it is now obsolete and it is being replaced by udev (my Fedora 15 didn’t even come with HAL installed anymore). So instead using HAL, I’ve tried to change the example to use udisks by doing the following:

  1. QDBusConnection::systemBus().connect(
  2.                          "org.freedesktop.UDisks", /*Changed Hal to UDisks*/
  3.                          "/org/freedesktop/UDisks",
  4.                          "org.freedesktop.UDisks",
  5.                          "DeviceAdded",
  6.                          this, SLOT(deviceAdded());
  7. QDBusConnection::systemBus().connect(
  8.                          "org.freedesktop.UDisks",
  9.                          "/org/freedesktop/UDisks",
  10.                          "org.freedesktop.UDisks",
  11.                          "DeviceRemoved",
  12.                          this, SLOT(deviceRemoved());
  13.  
  14. void deviceAdded(){
  15.                          qDebug() << "device added!";
  16. }
  17.  
  18. void deviceRemoved(){
  19.                          qDebug() << "device removed!";
  20. }

However this new code won’t work. Does anyone have any idea what I might be doing incorrectly?

10 replies

September 9, 2011

volviq volviq
Lab Rat
5 posts

I got exactly the same problem. HAL nowadays isn’t even started without requesting it, UDisks always runs.
But changing the paths as it would be intuitive does not lead to a successful signal.
In qdbusviewer I could connect to the signal, and it was successfully received.

September 9, 2011

volviq volviq
Lab Rat
5 posts

So, now I got a solution:
change the slots argument to the type: QDBusObjectPath, then it will be handled correctly

Example:

  1. QDBusConnection::systemBus().connect(
  2.                          "org.freedesktop.UDisks",
  3.                          "/org/freedesktop/UDisks",
  4.                          "org.freedesktop.UDisks",
  5.                          "DeviceAdded",
  6.                          this, SLOT(deviceAdded(QDBusObjectPath));
  7.  
  8. void deviceAdded(QDBusObjectPath dev){
  9.  
  10.                          qDebug() << "device added!"<<dev.path();
  11. }

In future cases, when the typing is unclear (I did not find the mapping from the “o” type in dbus to the corresponding type in qt, which is the QDBusObjectPath) just try first to receive the message as a QDBusMessage. You can print it out with qDebug and get more information about the type.
Another hint is to use the introspection with the qdbusviewer application. It will at least give you the arg type string “o” in this case.

Please tell, if it works..

September 9, 2011

volviq volviq
Lab Rat
5 posts

next problem: how can I access properties as they exist for each device?
Like for /dev/sdb1: DeviceIsMounted.

i did not find any documentation how to handle with DBus properties in qt.

September 11, 2011

ibingow ibingow
Lab Rat
20 posts

It’s my way, no dbus, only QtCore: http://developer.qt.nokia.com/forums/viewthread/9605/

September 12, 2011

volviq volviq
Lab Rat
5 posts

So, solution for my next last question:
“How can I access properties as they exist for each device?”
As mentioned in the code, I am not sure if there are way more elegant ways to deal with the variant types, but it works.

dbuspath is the dbus.path() from the previous question.
first, check if the device is really mounted:

  1.  QDBusMessage msg = QDBusMessage::createMethodCall(UDEV_SERV, dbuspath,
  2.    "org.freedesktop.DBus.Properties", "Get");
  3.  QList<QVariant> args;
  4.  args.append("org.freedesktop.UDisks.Device");
  5.  args.append("DeviceIsMounted");
  6.  msg.setArguments(args);
  7.  QDBusMessage reply;
  8.  reply = cnx.call(msg);
  9.  QString sig;
  10.  sig = 'v';
  11.  if (!reply.signature().compare(sig)) {
  12.   if (reply.arguments().length() == 1) {
  13.    bool ismounted;
  14.    qDebug() << "elem 1:" << reply.arguments().at(0);  
  15.    //not sure, if its the best way to handle those variants
  16.    QVariant var = reply.arguments().at(0);
  17.    QDBusVariant dbusVariant = qvariant_cast<QDBusVariant> (var);
  18.    QVariant result = dbusVariant.variant();
  19.    ismounted = result.toBool();
  20.    return ismounted;
  21.                        }
  22.              }

And then get the mountpath just alike:
  1.  QDBusMessage msg = QDBusMessage::createMethodCall(UDEV_SERV, dev.path(),
  2.     "org.freedesktop.DBus.Properties", "Get");
  3.  
  4.   QList<QVariant> args;
  5.   args.append("org.freedesktop.UDisks.Device");
  6.   args.append("DeviceMountPaths");
  7.   msg.setArguments(args);
  8.   QDBusMessage reply = cnx.call(msg);
  9.   QString sig;
  10.   sig = 'v';
  11.   if (!reply.signature().compare(sig)) {
  12.    if (reply.arguments().length() == 1) {
  13.     QString mount_path;
  14.     qDebug() << "elem 1:" << reply.arguments().at(0);
  15.     QVariant var = reply.arguments().at(0);
  16.     QDBusVariant dbusVariant = qvariant_cast<QDBusVariant> (var);
  17.     QVariant result = dbusVariant.variant();
  18.     mount_path = result.toString();
  19.     return mount_path;
  20.                                }
  21.                    }

September 12, 2011

volviq volviq
Lab Rat
5 posts

this really looks ugly, I am sorry. I did not have the time to read the guidelines for formatting the code in this forum. Do those exist? Where?
—> Updated the Code with “@“s. Thank You.

September 12, 2011

Lukas Geyer Lukas Geyer
Lab Rat
2068 posts

Just wrap your code into @ tags and it will got formatted properly.

September 13, 2011

ibingow ibingow
Lab Rat
20 posts

mount path is in /etc/mtab

November 30, 2012

sloanyang sloanyang
Lab Rat
1 posts

Hi, I am new here, and also have this problem. I add this code on my ubuntu 12.04 project.
Then it works! Thank you for your share.

volviq wrote:
So, now I got a solution:
change the slots argument to the type: QDBusObjectPath, then it will be handled correctly

Example:

  1. QDBusConnection::systemBus().connect(
  2.                          "org.freedesktop.UDisks",
  3.                          "/org/freedesktop/UDisks",
  4.                          "org.freedesktop.UDisks",
  5.                          "DeviceAdded",
  6.                          this, SLOT(deviceAdded(QDBusObjectPath));
  7.  
  8. void deviceAdded(QDBusObjectPath dev){
  9.  
  10.                          qDebug() << "device added!"<<dev.path();
  11. }

In future cases, when the typing is unclear (I did not find the mapping from the “o” type in dbus to the corresponding type in qt, which is the QDBusObjectPath) just try first to receive the message as a QDBusMessage. You can print it out with qDebug and get more information about the type.
Another hint is to use the introspection with the qdbusviewer application. It will at least give you the arg type string “o” in this case.

Please tell, if it works..

 Signature 

Hi, I come from Taiwan

July 16, 2013

sreeram sreeram
Lab Rat
14 posts

Hi sloanyang,

I am very new to Qt application, I want to use this code to my Qt application for usb hotplug support , I have posted my Qt hotplug problem in one of Qt forum.
Please read this following link for understand my usb hotplug problem

http://qt-project.org/forums/viewthread/30003/”

Can you guide me how can i use this code to my Qt application??????

Thanks
Sreeram

 
  ‹‹ Minimum size of static-linked Qt GUI app?      Is there any way to add more Qt::globalColor ? ››

You must log in to post a reply. Not a member yet? Register here!