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