signal matching
Giusti, Gisela
gisela.giusti at intel.com
Tue Aug 17 09:10:19 PDT 2010
Hi!
I am very new at dbus, so my doubts could be very basics... sorry for that.
I tried a couple of c++ examples using dbus-c++ bindings. I'm using dbus-c++-devel v0.5.0 package in a meego V1.0 release.
I coded a simple client-server from scratch in order to understand the functionality of DBus signals.
Here is my code:
Test.xml:
I have a method (Subscribe) and a signal (DataChanged)
<?xml version="1.0" ?>
<node name="/org/freedesktop/DBus/Test">
<interface name="org.freedesktop.DBus.Test">
<signal name="DataChanged">
<arg name="Data" type="s"/>
</signal>
<method name="Subscribe">
<arg type="s" name="DataName" direction="in"/>
</method>
</interface>
</node>
TestServer class:
class TestServer
: public org::freedesktop::DBus::Test_adaptor,
public DBus::ObjectAdaptor,
{
public:
TestServer(DBus::Connection &connection);
void Subscribe(const std::string& DataName);
};
And TestClient class:
class TestClient
: public DBus::ObjectProxy,
public org::freedesktop::DBus::Test_proxy
{
public:
TestClient(DBus::Connection& connection, const char * path, const char * name);
void DataChanged(const std::string& data);
};
TestServer implementation: Because I was trying to test signals, I emit the signal when the subscribe method is called. Also, I create another method, sendSignal to emit the signal and I attached it to SIGUSR1, this allows me to send the signal manually with the kill -10 <serverpid> command.
static const char *TEST_SERVER_NAME = "org.freedesktop.DBus.Test";
static const char *TEST_SERVER_PATH = "/org/freedesktop/DBus/Test";
TestServer::TestServer(DBus::Connection &connection)
: DBus::ObjectAdaptor(connection, TEST_SERVER_PATH)
{
}
TestServer * g_server;
DBus::BusDispatcher dispatcher;
void TestServer::Subscribe(const std::string& DataName)
{
std::cout<<DataName<<"has been subscribed"std::endl;
//Emiting the signal
g_server->DataChanged("subscription signal...");
}
void niam(int sig)
{
dispatcher.leave();
}
void sendSignal(int sig)
{
std::cout<<"Sending signal"<<std::endl;
g_server->DataChanged("something happens...");
}
int main()
{
signal(SIGTERM, niam);
signal(SIGINT, niam);
signal(SIGUSR1, sendSignal);
DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SessionBus();
conn.request_name(TEST_SERVER_NAME);
TestServer server(conn);
g_server = &server;
dispatcher.enter();
return 0;
}
Finally, this is the client code:
static const char *TEST_SERVER_NAME = "org.freedesktop.DBus.Test";
static const char *TEST_SERVER_PATH = "/org/freedesktop/DBus/Test";
TestClient::TestClient(DBus::Connection& connection, const char * path, const char * name):
DBus::ObjectProxy(connection,path,name)
{}
void TestClient::DataChanged(const std::string& data)
{
std::cout<<"Changed!"<<std::endl;
}
DBus::BusDispatcher dispatcher;
void niam(int sig)
{
dispatcher.leave();
}
int main()
{
signal(SIGTERM, niam);
signal(SIGINT, niam);
DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SessionBus();
//Why I need to match signals by hand???
conn.add_match("type='signal'");
TestClient client (conn, TEST_SERVER_PATH, TEST_SERVER_NAME);
client.Subscribe("Client0001");
dispatcher.enter();
return 0;
}
The thing is, if I didn't include the line conn.add_match("type='signal') the signal was not catched by the client (although it has been emited by the server). Im a bit confused because if you follow the Echo example in DBus sources, the add_match is never call, and it seems that the client part where the signal is catched is never executed. Is this because the binding is still incomplete? Calling the add_match("type='signal') is the right way if you want your client be notified of a server signal?
Thanks in advance!
Gisela
More information about the dbus
mailing list