Embedded Linux Qt Simple Dbus Example

Embedded Linux Qt Simple Dbus Example


DBus is a commonly used interprocess communication protocol ( IPC ) for

Linux. Qt offers excellent DBus support. This short example shows how to make very simple DBus "sender" and "receiver" programs that run as independent processes but can communicate over DBus. Qt 4.8.4 for Embedded Linux was used to generate these applications and of course, your target needs DBus installed.

In QtCreator, create a new project called "dbus-device-mode-receiver". Add a couple classes to the project, one named "devicemodeifadaptor" and one named "receiveDeviceModeChange".

Your dbus-device-mode-receiver.pro file should look like this:

#-------------------------------------------------

#

# Project created by QtCreator 2012-11-27T10:48:04

#

#-------------------------------------------------


QT += core

QT -= gui


# Add DBus on Unix systems

QT += dbus


TARGET = dbus-device-mode-receiver

CONFIG += console

CONFIG -= app_bundle


TEMPLATE = app


SOURCES += main.cpp \

devicemodeifadaptor.cpp \

receivedbusdevicemode.cpp


HEADERS += \

devicemodeifadaptor.h \

receivedbusdevicemode.h


# Install

target.path = /home/user

sources.path = /home/user

INSTALLS += target sources # install_lib


Now, your main.cpp file should look like this:


#include <QtCore/QCoreApplication>

#include "receivedbusdevicemode.h"


int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);


// Create a dbus instance

new ReceiveDbusDeviceMode();


return a.exec();

}


Your devicemodeifadaptor.h should look like this:


/*

* This file was generated by qdbusxml2cpp version 0.7

* Command line was: qdbusxml2cpp -c devicemodeifadaptor -a devicemodeifadaptor.h:devicemodeifadaptor.cpp com.company.device.mode.command.xml

*

* qdbusxml2cpp is Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).

*

* This is an auto-generated file.

* This file may have been hand-edited. Look for HAND-EDIT comments

* before re-generating it.

*/


#ifndef DEVICEMODEIFADAPTOR_H_1354045069

#define DEVICEMODEIFADAPTOR_H_1354045069


#include <QtCore/QObject>

#include <QtDBus/QtDBus>

class QByteArray;

template<class T> class QList;

template<class Key, class Value> class QMap;

class QString;

class QStringList;

class QVariant;


/*

* Adaptor class for interface com.company.project.device.command

*/

class devicemodeifadaptor: public QDBusAbstractAdaptor

{

Q_OBJECT

Q_CLASSINFO("D-Bus Interface", "com.company.project.device.command")

Q_CLASSINFO("D-Bus Introspection", ""

" <interface name=\"com.company.project.device.command\">\n"

" <method name=\"receiveDeviceModeChange\">\n"

" <arg direction=\"out\" type=\"s\"/>\n"

" <arg direction=\"in\" type=\"s\" name=\"cmd\"/>\n"

" </method>\n"

" </interface>\n"

"")

public:

devicemodeifadaptor(QObject *parent);

virtual ~devicemodeifadaptor();


public: // PROPERTIES

public Q_SLOTS: // METHODS

QString receiveDeviceModeChange(const QString &cmd);

Q_SIGNALS: // SIGNALS

};


#endif


Your devicemodeifadaptor.cpp should look like this:


/*

* This file was generated by qdbusxml2cpp version 0.7

* Command line was: qdbusxml2cpp -c devicemodeifadaptor -a devicemodeifadaptor.h:devicemodeifadaptor.cpp com.company.device.mode.command.xml

*

* qdbusxml2cpp is Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).

*

* This is an auto-generated file.

* Do not edit! All changes made to it will be lost.

*/


#include "devicemodeifadaptor.h"

#include <QtCore/QMetaObject>

#include <QtCore/QByteArray>

#include <QtCore/QList>

#include <QtCore/QMap>

#include <QtCore/QString>

#include <QtCore/QStringList>

#include <QtCore/QVariant>


/*

* Implementation of adaptor class devicemodeifadaptor

*/


devicemodeifadaptor::devicemodeifadaptor(QObject *parent)

: QDBusAbstractAdaptor(parent)

{

// constructor

setAutoRelaySignals(true);

}


devicemodeifadaptor::~devicemodeifadaptor()

{

// destructor

}


QString devicemodeifadaptor::receiveDeviceModeChange(const QString &cmd)

{

// handle method call com.company.project.device.command

QString out0;

QMetaObject::invokeMethod(parent(), "receiveDeviceModeChange", Q_RETURN_ARG(QString, out0), Q_ARG(QString, cmd));

return out0;

}


Your receivedbusdevicemode.h should look like this:


#ifndef DBUSMETHODMODEL_H

#define DBUSMETHODMODEL_H


#include "devicemodeifadaptor.h"

#include <QDebug>


class ReceiveDbusDeviceMode : public QObject

{


Q_OBJECT


// The interface will now be known as com.company.project.device.command

Q_CLASSINFO("D-Bus Interface", "com.company.project.device.command")


public:

ReceiveDbusDeviceMode(); // Constructor


public slots:


QString receiveDeviceModeChange(const QString &cmd);


};


#endif // DBUSMETHODMODEL_H


Your receivedbusdevicemode.cpp should look like this:


#include "receivedbusdevicemode.h"


ReceiveDbusDeviceMode::ReceiveDbusDeviceMode()

{


new devicemodeifadaptor(this); // Cleans itself up


QDBusConnection dbus = QDBusConnection::sessionBus(); // Use session bus


dbus.registerObject("/receive_mode_change",this); // Register object on the bus


dbus.registerService("com.company.project.device.command"); // Expose interface to others


}


// Basic test method for a string

QString ReceiveDbusDeviceMode::receiveDeviceModeChange(const QString &cmd)

{

qDebug() << "Received a device mode change! New mode is: " << cmd;


return cmd;

}


Your dbus-device-mode-sender.pro should look like this:


#-------------------------------------------------

#

# Project created by QtCreator 2012-11-27T11:32:35

#

#-------------------------------------------------


QT += core dbus

QT -= gui


TARGET = dbus-device-mode-sender

CONFIG += console

CONFIG -= app_bundle


TEMPLATE = app


SOURCES += main.cpp \

senddbusdevicemode.cpp


HEADERS += \

senddbusdevicemode.h


# Install

target.path = /home/user

sources.path = /home/user

INSTALLS += target sources # install_lib


Your main.cpp should look like this:


#include <QtCore/QCoreApplication>

#include <QtDBus/QtDBus>

#include "senddbusdevicemode.h"


int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);


SendDbusDeviceMode* client = new SendDbusDeviceMode("com.company.project.device.command", "/receive_mode_change", QDBusConnection::sessionBus(), 0);


qDebug() << "Sending Mode Change to Local...";

QString response = client->receiveDeviceModeChange("local");

qDebug() << "RESPONSE: " << response;


qDebug() << "Sending Mode Change to remote...";

response = client->receiveDeviceModeChange("remote");

qDebug() << "RESPONSE: " << response;

return a.exec();

}


Your senddbusdevicemode.h should look like this:


#ifndef SENDDBUSDEVICEMODE_H

#define SENDDBUSDEVICEMODE_H


#include <QtCore/QObject>

#include <QtCore/QByteArray>

#include <QtCore/QList>

#include <QtCore/QMap>

#include <QtCore/QString>

#include <QtCore/QStringList>

#include <QtCore/QVariant>

#include <QtDBus/QtDBus>


/*

* Proxy class for interface com.company.project.device

*/

class SendDbusDeviceMode: public QDBusAbstractInterface

{

Q_OBJECT


public:


static inline const char *staticInterfaceName() {

return "com.company.project.device.command";

}


public:


SendDbusDeviceMode(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);


~SendDbusDeviceMode();


public Q_SLOTS: // METHODS


// In protoReceiver it looks like:

// Basic test method for a string

// QString dbusReadWriteNvRam::SendMessage(const QString &cmd)

inline QDBusPendingReply<QString> receiveDeviceModeChange(const QString &cmd)

{

QList<QVariant> argumentList;

argumentList << QVariant::fromValue(cmd);

return asyncCallWithArgumentList(QLatin1String("receiveDeviceModeChange"), argumentList);

}


Q_SIGNALS: // SIGNALS

};


namespace com {

namespace company {

namespace project {

namespace device {

typedef ::SendDbusDeviceMode command;

}

}

}

}


#endif // SENDDBUSDEVICEMODE_H


Your senddbusdevicemode.cpp should look like this:


#include "senddbusdevicemode.h"


/*

* Implementation of interface class dbussender

*/


SendDbusDeviceMode::SendDbusDeviceMode(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)

{

}


SendDbusDeviceMode::~SendDbusDeviceMode()

{

}


Now build and launch the receiver app first, and then the sender app. You will see them communicate over DBus! Happy Coding :)




ClassyBits 2016