Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PropertiesChanged signal and support for org.freedesktop.DBus.Properties.GetAll #4

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions examples/properties/propsgs-client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,33 @@ PropsClient::PropsClient(DBus::Connection &connection, const char *path, const c
void PropsClient::MessageChanged(const std::string &message)
{
std::cout << "MessageChanged signal, new value: " << message << "\n";
};
}

void PropsClient::DataChanged(const double &data)
{
std::cout << "DataChanged signal, new value:" << data << "\n";
};
}

void PropsClient::PropertiesChanged(const std::string& interface,
const std::map<std::string, DBus::Variant>& changed_properties,
const std::vector<std::string>& invalidated_properties)
{
std::cout << "PropertiesChanged signal from interface " << interface
<< "\nChanged properties:\n";
std::map<std::string, DBus::Variant>::const_iterator it = changed_properties.begin();
while (it != changed_properties.end())
{
std::cout << " " << it->first << "\n";
++it;
}
std::cout << "Invalidated properties:\n";
std::vector<std::string>::const_iterator it2 = invalidated_properties.begin();
while (it2 != invalidated_properties.end())
{
std::cout << " " << *it2 << "\n";
++it2;
}
}

void *test_property_proxy(void *input)
{
Expand Down
4 changes: 4 additions & 0 deletions examples/properties/propsgs-client.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ class PropsClient
void MessageChanged(const std::string &message);

void DataChanged(const double &data);

void PropertiesChanged(const std::string& interface,
const std::map<std::string, DBus::Variant>& changed_properties,
const std::vector<std::string>& invalidated_properties);
};

#endif//__DEMO_PROPS_SERVER_H
3 changes: 3 additions & 0 deletions include/dbus-c++/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ const std::string &Interface::name() const
*/

typedef std::map< std::string, Slot<Message, const CallMessage &> > MethodTable;
typedef std::map< std::string, Variant > PropertyDict;

class DXXAPI InterfaceAdaptor : public Interface, public virtual AdaptorBase
{
Expand All @@ -144,6 +145,8 @@ class DXXAPI InterfaceAdaptor : public Interface, public virtual AdaptorBase

void set_property(const std::string &name, Variant &value);

PropertyDict *get_all_properties();

virtual IntrospectedInterface *introspect() const
{
return NULL;
Expand Down
28 changes: 27 additions & 1 deletion include/dbus-c++/property.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class PropertyAdaptor
return _data->value.operator T();
}

Variant value() const
{
return _data->value;
}

PropertyAdaptor &operator = (const T &t)
{
_data->value.clear();
Expand All @@ -75,6 +80,14 @@ class DXXAPI PropertiesAdaptor : public InterfaceAdaptor

Message Set(const CallMessage &);

Message GetAll(const CallMessage &);

/* signal emitter
*/
void PropertiesChanged(const std::string& interface,
const std::map<std::string, ::DBus::Variant>& changed_properties,
const std::vector<std::string>& invalidated_properties);

protected:

virtual void on_get_property(InterfaceAdaptor &/*interface*/, const std::string &/*property*/, Variant &/*value*/)
Expand All @@ -95,9 +108,22 @@ class DXXAPI PropertiesProxy : public InterfaceProxy
Variant Get(const std::string &interface, const std::string &property);

void Set(const std::string &interface, const std::string &property, const Variant &value);

std::map< std::string, ::DBus::Variant > GetAll(const std::string &interface);

/* signal handlers for this interface
*/
virtual void PropertiesChanged(const std::string& interface,
const std::map<std::string, ::DBus::Variant>& changed_properties,
const std::vector<std::string>& invalidated_properties) = 0;

private:

/* unmarshalers (to unpack the DBus message before calling the actual signal handler)
*/
void _PropertiesChanged_stub(const ::DBus::SignalMessage &sig);
};

} /* namespace DBus */

#endif//__DBUSXX_PROPERTY_H

2 changes: 1 addition & 1 deletion include/dbus-c++/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class DXXAPI Server
protected:

Server(const Server &s)
{}
{ (void)s; }

virtual void on_new_connection(Connection &c) = 0;

Expand Down
1 change: 1 addition & 0 deletions src/eventloop-integration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <dbus/dbus.h>

/* STD */
#include <unistd.h>
#include <string.h>
#include <cassert>
#include <sys/poll.h>
Expand Down
22 changes: 22 additions & 0 deletions src/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,28 @@ void InterfaceAdaptor::set_property(const std::string &name, Variant &value)
throw ErrorFailed("requested property not found");
}

PropertyDict *InterfaceAdaptor::get_all_properties()
{
PropertyTable::iterator pti;
PropertyDict *dict = new PropertyDict();

for (pti = _properties.begin(); pti != _properties.end(); ++pti)
{
// Skip unreadable properties
if (!pti->second.read)
continue;

Variant v = pti->second.value;
// Skip uninitialized properties
if (v.signature().empty())
continue;

std::string key = pti->first;
(*dict)[key] = v;
}
return dict;
}

InterfaceProxy *ProxyBase::find_interface(const std::string &name)
{
InterfaceProxyTable::const_iterator ii = _interfaces.find(name);
Expand Down
100 changes: 96 additions & 4 deletions src/property.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ PropertiesAdaptor::PropertiesAdaptor()
{
register_method(PropertiesAdaptor, Get, Get);
register_method(PropertiesAdaptor, Set, Set);
register_method(PropertiesAdaptor, GetAll, GetAll);
}

Message PropertiesAdaptor::Get(const CallMessage &call)
Expand All @@ -62,6 +63,9 @@ Message PropertiesAdaptor::Get(const CallMessage &call)
if (!value)
throw ErrorFailed("requested property not found");

if (value->signature().empty())
throw ErrorFailed("requested property has not been initialized");

on_get_property(*interface, property_name, *value);

ReturnMessage reply(call);
Expand Down Expand Up @@ -96,6 +100,45 @@ Message PropertiesAdaptor::Set(const CallMessage &call)
return reply;
}

Message PropertiesAdaptor::GetAll(const CallMessage &call)
{
MessageIter ri = call.reader();

std::string iface_name;
std::string property_name;
Variant value;

ri >> iface_name;

InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);

if (!interface)
throw ErrorFailed("requested interface not found");

PropertyDict *properties;
properties = interface->get_all_properties();

ReturnMessage reply(call);

MessageIter wi = reply.writer();

wi << *properties;
delete properties;
return reply;
}

void PropertiesAdaptor::PropertiesChanged(const std::string& interface,
const std::map<std::string, ::DBus::Variant>& changed_properties,
const std::vector<std::string>& invalidated_properties)
{
::DBus::SignalMessage sig("PropertiesChanged");
::DBus::MessageIter wi = sig.writer();
wi << interface;
wi << changed_properties;
wi << invalidated_properties;
emit_signal(sig);
}

IntrospectedInterface *PropertiesAdaptor::introspect() const
{
static IntrospectedArgument Get_args[] =
Expand All @@ -112,10 +155,17 @@ IntrospectedInterface *PropertiesAdaptor::introspect() const
{ "value", "v", true },
{ 0, 0, 0 }
};
static IntrospectedArgument GetAll_args[] =
{
{ "interface_name", "s", true },
{ "properties", "a{sv}", false },
{ 0, 0, 0 }
};
static IntrospectedMethod Properties_methods[] =
{
{ "Get", Get_args },
{ "Set", Set_args },
{ "GetAll", GetAll_args },
{ 0, 0 }
};
static IntrospectedMethod Properties_signals[] =
Expand All @@ -139,17 +189,59 @@ IntrospectedInterface *PropertiesAdaptor::introspect() const
PropertiesProxy::PropertiesProxy()
: InterfaceProxy(properties_name)
{
connect_signal(PropertiesProxy, PropertiesChanged, _PropertiesChanged_stub);
}

Variant PropertiesProxy::Get(const std::string &iface, const std::string &property)
{
//todo
Variant v;
return v;
CallMessage call;
call.member("Get");
call.interface("org.freedesktop.DBus.Properties");
MessageIter wi = call.writer();
wi << iface;
wi << property;
Message ret = this->invoke_method (call);
MessageIter ri = ret.reader ();
Variant argout;
ri >> argout;
return argout;
}

void PropertiesProxy::Set(const std::string &iface, const std::string &property, const Variant &value)
{
//todo
CallMessage call;
call.member("Set");
call.interface("org.freedesktop.DBus.Properties");
MessageIter wi = call.writer();
wi << iface;
wi << property;
wi << value;
Message ret = this->invoke_method (call);
}

std::map< std::string, ::DBus::Variant > PropertiesProxy::GetAll(const std::string &iface)
{
CallMessage call;
call.member("GetAll");
call.interface("org.freedesktop.DBus.Properties");
MessageIter wi = call.writer();
wi << iface;
Message ret = this->invoke_method (call);
MessageIter ri = ret.reader ();
std::map< std::string, ::DBus::Variant > argout;
ri >> argout;
return argout;
}

void PropertiesProxy::_PropertiesChanged_stub(const ::DBus::SignalMessage &sig)
{
::DBus::MessageIter ri = sig.reader();

std::string iface;
ri >> iface;
std::map< std::string, ::DBus::Variant > changed_properties;
ri >> changed_properties;
std::vector< std::string > invalidated_properties;
ri >> invalidated_properties;
PropertiesChanged(iface, changed_properties, invalidated_properties);
}
7 changes: 6 additions & 1 deletion test/functional/Test1/TestApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ TestApp::TestApp()
{
testList.push_back("test1");
testList.push_back("testByte");
testList.push_back("testPropChanged");

cout << "initialize DBus..." << endl;
initDBus();
Expand All @@ -43,7 +44,7 @@ void TestApp::initDBus()
g_testComIntro = &testComIntro;

cout << "Start server..." << endl;
TestAppIntroProvider testComProviderIntro(conn, &testComIntro);
TestAppIntroProvider testComProviderIntro(conn);
conn.request_name("DBusCpp.Test.Com.Intro");

mTestToDBusPipe = dispatcher.add_pipe(TestApp::testHandler, NULL);
Expand Down Expand Up @@ -103,4 +104,8 @@ void TestApp::testHandler(const void *data, void *buffer, unsigned int nbyte)
{
g_testComIntro->testByte(4);
}
else if (string(str) == "testPropChanged")
{
g_testComIntro->testPropChanged("secondValue");
}
}
18 changes: 18 additions & 0 deletions test/functional/Test1/TestAppIntro.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ using namespace std;
class TestAppIntro :
public DBusCpp::Test::Com::Intro_proxy,
public DBus::IntrospectableProxy,
public DBus::PropertiesProxy,
public DBus::ObjectProxy
{
public:
Expand All @@ -35,6 +36,23 @@ class TestAppIntro :
pthread_cond_signal(&mCondition);
}

void PropertiesChanged(const std::string& interface,
const std::map<std::string, DBus::Variant>& changed_properties,
const std::vector<std::string>& invalidated_properties)
{
cout << "PropertiesChanged on interface " << interface;
std::map<std::string, DBus::Variant>::const_iterator it = changed_properties.find("testProperty");
if (changed_properties.end() != it &&
changed_properties.size() == 1 &&
invalidated_properties.empty())
{
cout << " with value " << it->second.operator std::string();
mTestResult = true;
}
cout << endl;
pthread_cond_signal(&mCondition);
}

private:
pthread_cond_t &mCondition;
bool &mTestResult;
Expand Down
8 changes: 7 additions & 1 deletion test/functional/Test1/TestAppIntro.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<signal name="test1Result">
</signal>

<method name="testByte">
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
<arg type="y" name="Byte" direction="in"/>
Expand All @@ -18,6 +18,12 @@
<arg type="y" name="Byte" direction="in"/>
</signal>

<method name="testPropChanged">
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
<arg type="s" name="val" direction="in"/>
</method>

<property name="testProperty" type="s" access="readwrite"/>

</interface>
</node>
Loading