FU Logo
  • Startseite
  • Kontakt
  • Impressum
  • Home
  • Listenauswahl
  • Anleitungen

Re: [linux-minidisc] netmd support for qhimdtransfer gui application

<-- thread
<-- date
  • From: Thomas Arp <manner.moe@gmx.de>
  • To: "linux-minidisc@lists.fu-berlin.de" <linux-minidisc@lists.fu-berlin.de>
  • Date: Sun, 29 Dec 2013 16:32:14 +0100
  • Subject: Re: [linux-minidisc] netmd support for qhimdtransfer gui application

Am 28.12.2013 20:38, schrieb Thomas Arp:
Am 25.12.2013 20:59, schrieb Thomas Arp:
Hi,

here is a new feature corresponding to my netmd integration patch.
This can be applied after patch #10.

I know, my patch is not reviewed jet, but i just want this to be added to the "to review list".

This includes unix netmd and himd autotetection during application runtime (netmd autodetection at application start is already implemented). Himd autodetection at application start is missing yet, also himd autodetection during application runtime does not work correctly.
The detection works, but not the function getting the mountpoint.
I can fetch the mountpoint for the detected device from UDisks2 through dbus but the value returned cannot be converted yet (see comments in the files).

Thomas


O.K., I fixed the function for getting the mountpoint, only himd detection at application start is missing now. By examining the qdbusviewer and qdbus source codes, i implemented functions that can convert a QVariant to a QString if the QVariant cannot be converted automatically (unknown/unsupported value).
Patch can be applied after the last patch #12

Thomas

>From beb071d936e18c815d7f837f63e80e0638f68b40 Mon Sep 17 00:00:00 2001
From: Thomas Arp <manner.moe@gmx.de>
Date: Sun, 29 Dec 2013 16:22:52 +0100
Subject: [PATCH 13/13] unix autodetection: fixed getting mountpoit function for
 himd devices

---
 netmd/etc/minidisc_notify.sh         |    4 +-
 qhimdtransfer/qhimddetection.cpp     |    1 +
 qhimdtransfer/qhimdunixdetection.cpp |  181 ++++++++++++++++++++++++++++------
 qhimdtransfer/qhimdunixdetection.h   |    3 +
 qhimdtransfer/qmddevice.cpp          |   13 +++
 qhimdtransfer/qmddevice.h            |    5 +-
 6 files changed, 172 insertions(+), 35 deletions(-)

diff --git a/netmd/etc/minidisc_notify.sh b/netmd/etc/minidisc_notify.sh
index 94bf138..cd714a5 100644
--- a/netmd/etc/minidisc_notify.sh
+++ b/netmd/etc/minidisc_notify.sh
@@ -21,5 +21,5 @@ export DISPLAY=:0.0
 vid=$(echo $((0x$ID_VENDOR_ID)))
 pid=$(echo $((0x$ID_MODEL_ID)))
 
-# send message to session bus
-su $username -c "qdbus --session com.trolltech.Qt /QHiMDUnixDetection $ACT $DEVNAME $vid $pid" -m
+# send message to session bus, do not wait for a reply !!! 
+su $username -c "qdbus --session com.trolltech.Qt /QHiMDUnixDetection $ACT $DEVNAME $vid $pid &" -m
diff --git a/qhimdtransfer/qhimddetection.cpp b/qhimdtransfer/qhimddetection.cpp
index e73dc03..fc893ba 100644
--- a/qhimdtransfer/qhimddetection.cpp
+++ b/qhimdtransfer/qhimddetection.cpp
@@ -84,6 +84,7 @@ void QHiMDDetection::scan_for_minidisc_devices()
     QHiMDDevice * mddev = new QHiMDDevice();
     mddev->setMdInserted(true);
     mddev->setName("disc image");
+    mddev->setDeviceFile(QString());
     dlist.append(mddev);
     emit deviceListChanged(dlist);
 
diff --git a/qhimdtransfer/qhimdunixdetection.cpp b/qhimdtransfer/qhimdunixdetection.cpp
index 3cb59c8..454a5bb 100644
--- a/qhimdtransfer/qhimdunixdetection.cpp
+++ b/qhimdtransfer/qhimdunixdetection.cpp
@@ -1,6 +1,8 @@
 #include "qhimdunixdetection.h"
 #include <QVariantList>
 #include <QDebug>
+#include <QFileDialog>
+#include <QMessageBox>
 #include <QApplication>
 
 QHiMDDetection * createDetection(QObject * parent)
@@ -8,18 +10,82 @@ QHiMDDetection * createDetection(QObject * parent)
     return new QHiMDUnixDetection(parent);
 }
 
+/* following static functions are stolen from qtdbusutil.cpp, return value of get_property() for the mountpoint is an array of QByteArrays,
+ * cropped unneeded parts, characters and spaces here and changed the output character type from QString::number() to QChar
+ * */
+static bool argToString(const QDBusArgument &busArg, QString &out);
+
+static bool variantToString(const QVariant &arg, QString &out)
+{
+    int argType = arg.userType();
+
+     if (argType == QVariant::ByteArray)
+     {
+        QByteArray list = arg.toByteArray();
+        for (int i = 0; i < list.count(); ++i)
+            out += QChar(list.at(i));
+    }
+    else if (argType == qMetaTypeId<QDBusArgument>())
+     {
+        argToString(qvariant_cast<QDBusArgument>(arg), out);
+     }
+    else if (argType == qMetaTypeId<QDBusVariant>())
+    {
+        const QVariant v = qvariant_cast<QDBusVariant>(arg).variant();
+
+        if (!variantToString(v, out))
+            return false;
+    }
+    return true;
+}
+
+static bool argToString(const QDBusArgument &busArg, QString &out)
+{
+    bool doIterate = false;
+    QDBusArgument::ElementType elementType = busArg.currentType();
+
+    switch (elementType)
+    {
+        case QDBusArgument::BasicType:
+        case QDBusArgument::VariantType:
+            if (!variantToString(busArg.asVariant(), out))
+                return false;
+            break;
+        case QDBusArgument::ArrayType:
+            busArg.beginArray();
+            doIterate = true;
+            break;
+        case QDBusArgument::UnknownType:
+        default:
+            return false;
+    }
+
+    if (doIterate && !busArg.atEnd()) {
+        while (!busArg.atEnd()) {
+            if (!argToString(busArg, out))
+                return false;
+            out += QLatin1String(" , ");
+        }
+        out.chop(3);
+    }
+
+    if(elementType == QDBusArgument::ArrayType)
+        busArg.endArray();
+    return true;
+}
+
 QHiMDUnixDetection::QHiMDUnixDetection(QObject *parent)
   : QHiMDDetection(parent), had(new QHiMDAdaptor(this)),
     dbus_sys(QDBusConnection::connectToBus( QDBusConnection::SystemBus, "system" ) ),
     dbus_ses(QDBusConnection::connectToBus(QDBusConnection::SessionBus, "com.trolltech.Qt"))
 {
     if(!dbus_sys.isConnected())
-        qDebug() << "cannot connect to system bus";
+        qDebug() << tr("cannot connect to system bus");
     if(!dbus_ses.isConnected())
-        qDebug() << "cannot connect to session bus";
+        qDebug() << tr("cannot connect to session bus");
 
     if(!dbus_ses.registerObject("/QHiMDUnixDetection", this, QDBusConnection::ExportAllSlots))
-        qDebug() << "cannot register dbus interface object ";
+        qDebug() << tr("cannot register dbus interface object ");
 
     // register interface to session bus to make it visible to all other connections
     dbus_ses.interface()->registerService("com.trolltech.Qt");
@@ -33,7 +99,6 @@ QHiMDUnixDetection::QHiMDUnixDetection(QObject *parent)
 QVariant QHiMDUnixDetection::get_property(QString udiskPath, QString property, QString interface)
 {
     QDBusMessage msg = QDBusMessage::createMethodCall(UDISK_SERVICE, udiskPath, UDISK_PROPERTIES, "Get");
-    QVariant var;
     QList<QVariant> args;
     QDBusMessage reply;
 
@@ -46,29 +111,83 @@ QVariant QHiMDUnixDetection::get_property(QString udiskPath, QString property, Q
     reply = dbus_sys.call(msg);
 
     if (!reply.signature().compare(QString(QChar('v'))) && reply.arguments().length() >0)
-            var = reply.arguments().at(0);
+        return reply.arguments().at(0);
     else
         return QVariant();
-
-    return var;
 }
 
 QString QHiMDUnixDetection::mountpoint(QString devpath)
 {
     QString udev_path = UDISK_DEVICE_PATH;
-    QVariant mp;
+    QVariant ret;
+    QString mp;
 
     // setup correct path for UDisk operations, just need sd* instead fo /dev/sd*
     devpath.remove(0, devpath.lastIndexOf("/")+1);
     udev_path.append(devpath);
 
-    /* TODO: convert return value of get_property() in order to extract needed data, the returned value is marked as INVALID and cannot be converted,
-     * it should contain something like this (this is a sample of what qdbusviewer returns, here: "/media/man2/disk"):
-     *         Arguments: [Variant: [Argument: aay {{47, 109, 101, 100, 105, 97, 47, 109, 97, 110, 50, 47, 100, 105, 115, 107, 0}}]]
-     * so we have to convert the udev "aay" format (array of filepaths) to something readable
+    ret = get_property(udev_path, PROP_MOUNTPATH, UDISK_FILESYSTEM);
+    if(!ret.isValid())
+        return QString();
+
+    /* try to read mountpoint as string
+     * as this is an array of /0 terminatined ByteArrays it returns first mointpoint only because of the terminating /0 character
+     * this is fine for now and matches our needs
      */
-    mp = get_property(udev_path, PROP_MOUNTPATH, UDISK_FILESYSTEM);
-    return mp.toString();
+    if(!variantToString(ret, mp))
+        return QString();
+
+    return mp;
+}
+
+QMDDevice *QHiMDUnixDetection::find_by_deviceFile(QString file)
+{
+    QMDDevice * mddev;
+
+    foreach(mddev, dlist)
+    {
+        if(mddev->deviceFile() == file)
+            return mddev;
+    }
+    return NULL;
+}
+
+void QHiMDUnixDetection::add_himddevice(QString file, QString path, QString name)
+{
+    if (find_by_deviceFile(file))
+        return;
+
+    QHiMDDevice * new_device = new QHiMDDevice();
+
+    new_device->setDeviceFile(file);
+    new_device->setBusy(false);
+    new_device->setPath(path);
+    new_device->setName(name);
+    new_device->setMdInserted(true);
+
+    dlist.append(new_device);
+    emit deviceListChanged(dlist);
+}
+
+void QHiMDUnixDetection::remove_himddevice(QString file)
+{
+    int index = -1;
+    QMDDevice * dev;
+
+    if (!(dev = find_by_deviceFile(file)))
+        return;
+
+    index = dlist.indexOf(dev);
+
+    if(dev->isOpen())
+        dev->close();
+
+    delete dev;
+    dev = NULL;
+
+    dlist.removeAt(index);
+
+    emit deviceListChanged(dlist);
 }
 
 void QHiMDUnixDetection::AddMDDevice(QString deviceFile, int vid, int pid)
@@ -84,8 +203,8 @@ void QHiMDUnixDetection::AddMDDevice(QString deviceFile, int vid, int pid)
      */
     if(name.contains("NetMD"))
     {
-        qDebug() << "qhimdtransfer detection: netmd device detected: " + name;
-        QThread::msleep(5000); // wait for TOC to be loaded by the device, else tracklist may by shown correctly (no tiltles, unknown codec etc.)
+        qDebug() << tr("qhimdtransfer detection: netmd device detected: %1").arg(name);
+        QThread::msleep(5000); // wait for TOC to be loaded by the device, else tracklist may not by shown correctly (no tiltles, unknown codec etc.)
         rescan_netmd_devices();
         return;
     }
@@ -94,23 +213,22 @@ void QHiMDUnixDetection::AddMDDevice(QString deviceFile, int vid, int pid)
     if(!deviceFile.startsWith("/dev/sd"))
         return;
 
+    qDebug() << tr("qhimdtransfer detection: himd device detected at %1: %2").arg(deviceFile).arg(name);
 
-    qDebug() << QString("qhimdtransfer detection: himd device detected at %1: %2").arg(deviceFile).arg(name);
-
-    // wait for device to be mounted by polling for mountpoint, this could take some time
-    // break if mount process did not finish within 30 seconds
-    for(int i = 0; i < 30; i++)
+    // wait for device to be mounted by polling for mountpoint, break if mount process takes too long
+    for(int i = 0; i < 20; i++)
     {
-        QThread::msleep(1000);
-        QApplication::processEvents();  // prevent application to be blocked completely
+        QApplication::processEvents();  // prevent application from beeing blocked
+        QThread::sleep(1);
         if(!(mountpt = mountpoint(deviceFile)).isEmpty())
-                break;
+            break;
     }
-    qDebug() << (mountpt.isEmpty() ? "no mountpoint detected" : QString("device mounted at: %1").arg(mountpt));
 
-    /* TODO: add new QHiMDDevice object to device list here,
-     * as mountpoint() function does not work correctly yet, this cannot be done at current stage of the code
-     */
+    // if mountpoint detection fails return, alternatively ask user to provide mountpoint with a QFileDialog
+    if(mountpt.isEmpty())
+            return;
+
+    add_himddevice(deviceFile,mountpt,name);
 
 }
 
@@ -124,7 +242,7 @@ void QHiMDUnixDetection::RemoveMDDevice(QString deviceFile, int vid, int pid)
 
     if(name.contains("NetMD"))
     {
-        qDebug() << "qhimdtransfer detection: netmd device removed: " + name;
+        qDebug() << tr("qhimdtransfer detection: netmd device removed: ").arg(name);
         rescan_netmd_devices();
         return;
     }
@@ -133,9 +251,8 @@ void QHiMDUnixDetection::RemoveMDDevice(QString deviceFile, int vid, int pid)
     if(!deviceFile.startsWith("/dev/sd"))
         return;
 
-    qDebug() << QString("qhimdtransfer detection: himd device removed at %1: %2").arg(deviceFile).arg(name);
-
-    /* TODO: remove corresponding QHiMDDevice object from device list here */
+    qDebug() << tr("qhimdtransfer detection: himd device removed at %1: %2").arg(deviceFile).arg(name);
 
+    remove_himddevice(deviceFile);
 }
 
diff --git a/qhimdtransfer/qhimdunixdetection.h b/qhimdtransfer/qhimdunixdetection.h
index 74e0fe9..c6e198b 100644
--- a/qhimdtransfer/qhimdunixdetection.h
+++ b/qhimdtransfer/qhimdunixdetection.h
@@ -62,6 +62,9 @@ public:
 private:
     QVariant get_property(QString udiskPath, QString property, QString interface);
     QString mountpoint(QString devpath);
+    QMDDevice *find_by_deviceFile(QString file);
+    void add_himddevice(QString file, QString path, QString name);
+    virtual void remove_himddevice(QString file);
 
 public slots:
     void AddMDDevice(QString deviceFile, int vid, int pid);
diff --git a/qhimdtransfer/qmddevice.cpp b/qhimdtransfer/qmddevice.cpp
index 35e01a8..3f60cb3 100644
--- a/qhimdtransfer/qmddevice.cpp
+++ b/qhimdtransfer/qmddevice.cpp
@@ -36,6 +36,17 @@ QString QMDDevice::path()
     return device_path;
 }
 
+void QMDDevice::setDeviceFile(QString file)
+{
+    device_file = file;
+}
+
+QString QMDDevice::deviceFile()
+{
+    return device_file;
+}
+
+
 void QMDDevice::setName(QString name)
 {
     recorder_name = name;
@@ -119,6 +130,7 @@ void QMDDevice::checkfile(QString UploadDirectory, QString &filename, QString ex
 QNetMDDevice::QNetMDDevice()
 {
     dev_type = NETMD_DEVICE;
+    device_file = QString();
     devh = NULL;
     netmd = NULL;
     is_open = false;
@@ -354,6 +366,7 @@ void QNetMDDevice::batchUpload(QMDTrackIndexList tlist, QString path)
 QHiMDDevice::QHiMDDevice()
 {
     dev_type = HIMD_DEVICE;
+    device_file = QString();
     himd = NULL;
     is_open = false;
 }
diff --git a/qhimdtransfer/qmddevice.h b/qhimdtransfer/qmddevice.h
index c413f9c..ef9974e 100644
--- a/qhimdtransfer/qmddevice.h
+++ b/qhimdtransfer/qmddevice.h
@@ -21,6 +21,7 @@ class QMDDevice : public QObject {
     bool is_busy;
 protected:
     QString device_path;
+    QString device_file;
     enum device_type dev_type;
     bool is_open;
     unsigned int trk_count;
@@ -32,8 +33,10 @@ public:
     explicit QMDDevice();
     virtual ~QMDDevice();
     virtual enum device_type deviceType();
-    virtual void setPath(QString path);
+    virtual void setPath(QString path);    
     virtual QString path();
+    virtual void setDeviceFile(QString file);
+    virtual QString deviceFile();
     virtual void setName(QString name);
     virtual QString name();
     virtual void setBusy(bool busy);
-- 
1.7.10.4

<-- thread
<-- date
  • References:
    • [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd support for qhimdtransfer gui application
      • From: Thomas Arp <manner.moe@gmx.de>
  • linux-minidisc - December 2013 - Archives indexes sorted by:
    [ thread ] [ subject ] [ author ] [ date ]
  • Complete archive of the linux-minidisc mailing list
  • More info on this list...

Hilfe

  • FAQ
  • Dienstbeschreibung
  • ZEDAT Beratung
  • postmaster@lists.fu-berlin.de

Service-Navigation

  • Startseite
  • Listenauswahl

Einrichtung Mailingliste

  • ZEDAT-Portal
  • Mailinglisten Portal