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:
    @
    QDBusConnection::systemBus().connect(
    "org.freedesktop.Hal",
    "/org/freedesktop/Hal/Manager",
    "org.freedesktop.Hal.Manager",
    "DeviceAdded",
    this, SLOT(deviceAdded());
    QDBusConnection::systemBus().connect(
    "org.freedesktop.Hal",
    "/org/freedesktop/Hal/Manager",
    "org.freedesktop.Hal.Manager",
    "DeviceRemoved",
    this, SLOT(deviceRemoved());

    void deviceAdded(){
    qDebug() << "device added!";
    }

    void deviceRemoved(){
    qDebug() << "device removed!";
    }
    @

    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:
    @
    QDBusConnection::systemBus().connect(
    "org.freedesktop.UDisks", /Changed Hal to UDisks/
    "/org/freedesktop/UDisks",
    "org.freedesktop.UDisks",
    "DeviceAdded",
    this, SLOT(deviceAdded());
    QDBusConnection::systemBus().connect(
    "org.freedesktop.UDisks",
    "/org/freedesktop/UDisks",
    "org.freedesktop.UDisks",
    "DeviceRemoved",
    this, SLOT(deviceRemoved());

    void deviceAdded(){
    qDebug() << "device added!";
    }

    void deviceRemoved(){
    qDebug() << "device removed!";
    }
    @

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



  • 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.



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

    Example:
    @
    QDBusConnection::systemBus().connect(
    "org.freedesktop.UDisks",
    "/org/freedesktop/UDisks",
    "org.freedesktop.UDisks",
    "DeviceAdded",
    this, SLOT(deviceAdded(QDBusObjectPath));

    void deviceAdded(QDBusObjectPath dev){

                         qDebug() << "device added!"<<dev.path();
    

    }
    @

    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..



  • 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.



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



  • 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:
    @
    QDBusMessage msg = QDBusMessage::createMethodCall(UDEV_SERV, dbuspath,
    "org.freedesktop.DBus.Properties", "Get");
    QList<QVariant> args;
    args.append("org.freedesktop.UDisks.Device");
    args.append("DeviceIsMounted");
    msg.setArguments(args);
    QDBusMessage reply;
    reply = cnx.call(msg);
    QString sig;
    sig = 'v';
    if (!reply.signature().compare(sig)) {
    if (reply.arguments().length() == 1) {
    bool ismounted;
    qDebug() << "elem 1:" << reply.arguments().at(0);
    //not sure, if its the best way to handle those variants
    QVariant var = reply.arguments().at(0);
    QDBusVariant dbusVariant = qvariant_cast<QDBusVariant> (var);
    QVariant result = dbusVariant.variant();
    ismounted = result.toBool();
    return ismounted;
    }
    }

    @
    And then get the mountpath just alike:
    @
    QDBusMessage msg = QDBusMessage::createMethodCall(UDEV_SERV, dev.path(),
    "org.freedesktop.DBus.Properties", "Get");

    QList<QVariant> args;
    args.append("org.freedesktop.UDisks.Device");
    args.append("DeviceMountPaths");
    msg.setArguments(args);
    QDBusMessage reply = cnx.call(msg);
    QString sig;
    sig = 'v';
    if (!reply.signature().compare(sig)) {
    if (reply.arguments().length() == 1) {
    QString mount_path;
    qDebug() << "elem 1:" << reply.arguments().at(0);
    QVariant var = reply.arguments().at(0);
    QDBusVariant dbusVariant = qvariant_cast<QDBusVariant> (var);
    QVariant result = dbusVariant.variant();
    mount_path = result.toString();
    return mount_path;
    }
    }
    @



  • 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.



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



  • mount path is in /etc/mtab



  • 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.
    [quote author="volviq" date="1315569314"]So, now I got a solution:
    change the slots argument to the type: QDBusObjectPath, then it will be handled correctly

    Example:
    @
    QDBusConnection::systemBus().connect(
    "org.freedesktop.UDisks",
    "/org/freedesktop/UDisks",
    "org.freedesktop.UDisks",
    "DeviceAdded",
    this, SLOT(deviceAdded(QDBusObjectPath));

    void deviceAdded(QDBusObjectPath dev){

                         qDebug() << "device added!"<<dev.path();
    

    }
    @

    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..[/quote]



  • 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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.