Skip to main content

Qt Dbus Communication

Qt Dbus Communication


What is a Dbus?
Dbus is an inter-process communication system. It allows two individual processes to communicate with each other. It is available in Linux based and Unix based systems.

How does qt Support dbus communication?
Qt provides a module called QtDBus module. It is a Unix-only library which can be used to perform IPCs (Inter Process Communication)

However if you want two processes to start communicating with each using dbus certain initial setup has to be done. And the two communicating processes will be obligated to follow a contract.
The contract is enforced by a user defined interface.

Let’s try and have two processes communicate with each other using dbus.

Here in our example let’s implement a client and server to illustrate dbus communication.
Before we create the server process, the server process should provide certain services which can be accessed by clients.

This service is defined by the user defined interface. So our first job would be to define an interface.

We shall define an interface using an xml document; later the xml file shall be converted to regular C++ class using a tool called “qbusxml2cpp


Create an xml file and name it as “com.inter.Demo.xml”. The naming of the xml file is a dotted filename; it is similar to a network address of a host computer. The dotted sequence convention has been followed to name the interface.

The xml File should contain the following:              

<node>
     <interface name="com.inter.Demo">
            <method name="AddTwoNumbers">
                        <arg name="expr1" type="s" direction="in" />
                        <arg name="expr2" type="s" direction="in" />
            </method>

            <method name="Display"/>
            <signal name="MySignal">
                        <arg name="eventkind" type="s" directon="out" />
            </signal>
     </interface>
</node>

com.inter.Demo.xml

The above displayed xml file tells that the name of the interface is “com.inter.Demo” (the one which was earlier told to enforce a contract) It contains two slots (basically methods) and a signal.
The name of one of the methods is “AddTwoNumbers” it takes two arguments. The type=”s” specifies the argument type is a string, the direction=”in” specifies it as an input parameter.
The other method defined in this interface is “display” it takes no arguments or whatsoever.
We have a signal called “MySignal” that has one parameter. This can be used when this signal is being emitted from a slot or any method.

Once, the interface file in xml is written we can generate the adaptor classes (server related C++ files) and client proxies (Client related C++ files) using the “qdbusxml2cpp” tool.
Now, Lets create the adaptor class from the “com.inter.Demo.xml” file
It can be created using the following command:

$ qdbusxml2cpp -c MyServer -a myServer.h:myServer.cpp com.inter.Demo.xml


The above command creates two adaptor class files “myServer.h” and “myServer.cpp” with the class name “MyServer”.
The .h and .cpp files that just got generated in the current directory will have the 2 methods and a signal that we defined in the interface file.
Next, we need to create a new project and make use of the created adaptor class.
Create a new project name it as “ALU_DBUS” (or whatever is convenient to you). To that project add a new C++ file and name it “MyDemo” (or whatever is convenient to you). Now, we need to make the signal and slots of “MyDemo.h” look the same as that of “myServer.h”. Before we do that we need to copy the “myServer.h” and “myServer.cpp” to the current project.

After adding the files and copying the signals and slot sections, the signal and slot section of “MyDemo.h” will look like this

public Q_SLOTS: // METHODS
    void AddTwoNumbers(const QString &expr1, const QString &expr2);
    void Display();
Q_SIGNALS: // SIGNALS
    void MySignal(const QString &eventkind);

After adding the files and copying the signals and slot sections, the signal and slot section of “MyDemo.h” will look like this

void MyDemo::AddTwoNumbers(const QString &expr1, const QString &expr2)
{
    // handle method call com.inter.Demo.AddTwoNumbers
    QMetaObject::invokeMethod(parent(), "AddTwoNumbers", Q_ARG(QString, expr1), Q_ARG(QString, expr2));
    qDebug()<<"Inside add two numbers";

    qDebug()<< "Addition of two number is "<< (expr1.toInt() + expr2.toInt());
}

void MyDemo::Display()
{
    // handle method call com.inter.Demo.Display
    QMetaObject::invokeMethod(parent(), "Display");
    qDebug() << " I am in Display";
}
After implementing the slots in the MyDemo.cpp file we need to expose these services to the external clients. So, we need to create a Dbus connection. Before that create an instance of MyDemo and make it as a parent to the instance of the adaptor class ie., MyServer’s class

MyDemo *myServer = new MyDemo;
    new DemoMyServer(myServer);

The Dbus connection in Qt can be created using the following statement:

 QDBusConnection connection = QDBusConnection::sessionBus();

What the above statement does is that it creates a seesionBus() to communicate between processes and returns an object of that bus. To Know more about sessionBus follow the link: ( http://qt-project.org/doc/qt-5/qdbusconnection.html#send )  


After the session bus is created we need to register our service (the service that we are offering via the interfaces we wrote in the xml) In other words, once we register our service we can let the clients access the methods we offer via the dbus.
bool ret = connection.registerService("com.inter.Demo");
 
We can register our service with the following statement:





Registering a service will define a contract on the bus but, we can only expose it through an object,that can be done using the statement:

    ret = connection.registerObject("/",myServer);

Here the “/” is the object path and “myServer” is the Service offering instance/object.
NOTE: In the .pro file add QT += dbus

Making use of the Service that we made available
We need to create the client proxy class which can make use of the service which we are publishing. We can generate these two files from the “com.inter.Demo.xml” (the interface file that we created initially).  The files can be created from the qbusxml2cpp tool, it can be done as follows: 

$ qdbusxml2cpp -v -c DemoMyClient -p demoMyClient.h: demoMyClient.cpp com.inter.Demo.xml

 

After you execute this command two files will be created. We need to instantiate these two files to make use of the services. Create a new project, copy these two files in that project. Create an instance of DemoMyClient, register it with the dbus that has been created and use the services that are exposed by the object.

It can be done using the following statement:

DemoMyClient *client1 = new DemoMyClient("com.inter.Demo","/",QDBusConnection::sessionBus(),0);

The offered services can be called just like local services
   client1->AddTwoNumbers(num1,num2);
   client1->Display();

 
 



NOTE: In the .pro file add QT += dbus


(Note: the Dbus Server should already be running, now run the Client project you should see that both the services that were offered by another process were utilized by client process. Thus the IPC has been achieved)
To summarize what we have done so far, we can put it in points below:
1.     Create an interface file in xml
2.     Use the xml2cpp tool to generate the adaptor class
3.     Use the adaptor class in a new project and implement the services
4.     Create a session bus(dbus)  to make the communication possible b/w 2 process
5.     Register the services (the contract defined by the interface) with the dbus connection
6.     Register the Object so that services can be exposed through this object
7.     Create the Client proxies so that the exposed services can be accessed
8.     Instantiate the Client Proxy with the registered service on the bus with the appropriate object
9.     Start calling the methods of server using client object just like local methods
10.  Dbus communication is achieved using Qt


More on QtDBus can be found here (http://qt-project.org/doc/qt-5/qtdbus-index.html ) 

Comments

Post a Comment

Popular posts from this blog

IISc PhD interviews (2018) CSA & CDS

Hello everyone, Just wanted to share my experience regarding the recent PhD interviews in IISc, so that anyone who is interested in pursuing research in Computer Science at IISc can get some sort of intro/prelude before they get to the process. I'll break it up into important titles so that you can pick what is relevant for you. Application Dates : The portal for the research admissions open sometime in 1st week of Febraury and I think it'll be open till Mid March. link:  https://www.iisc.ac.in/important-dates/ Shortlisting Criteria: So for the Computer Science Department, there were 2 ways of getting shortlisted which were relevant to me, I'll list them below. 1. GATE score (should be valid at the time of applying) 2. M.Tech qualified. (Should have completed the degree) 3. ERP (External Registration Programme) should be sponsored by a company in which you are working My GATE score had expired,  so I managed to qualify in the second category and got

The PhD programme - Top 5 things

Hey there! So for those of you who are jumping into a PhD programme, this might be useful.  Here are the top 5 things which you need to consider   before you make that big decision . 1. Choose your advisor wisely It goes without saying that this is the most important thing to consider. Mainly because it has direct saying on the projects that you’ll be working on. Think of it as a marriage, your decision should be well thought out because it is a huge commitment which has bearing throughout your life. Once you make that decision, it stays for all your lifetime( literally, your advisor’s recommendation will matter for all your future employment). This decision is paramount. 2. Choose your research field wisely.   I’ll figure out when I get there, instead of this, do your homework. Identifying what your interests are is a big strength, think of it as a lighthouse when you are traveling in the sea. It serves as a direction when you are off-course from your goal for s