[bluemonkey] - dbus module meta object
authorKevron Rees <kevron.m.rees@intel.com>
Tue, 17 Feb 2015 17:07:40 +0000 (09:07 -0800)
committerKevron Rees <kevron.m.rees@intel.com>
Tue, 17 Feb 2015 17:07:40 +0000 (09:07 -0800)
CMakeLists.txt
README.md
plugins/bluemonkey/CMakeLists.txt
plugins/bluemonkey/bluemonkey.cpp
plugins/bluemonkey/bluemonkey.h
plugins/bluemonkey/bmdbus.cpp
plugins/bluemonkey/bmdbus.h
plugins/bluemonkey/bmdbus_p.h [new file with mode: 0644]
plugins/bluemonkey/config.js

index f5b4ce2..5d88c1b 100644 (file)
@@ -1,5 +1,5 @@
 project(automotive-message-broker)
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.11)
 
 set(CMAKE_BUILD_TYPE, Debug)
 
@@ -47,6 +47,7 @@ option(enable_docs "enable Doxygen doc generation" OFF)
 option(usebluez5 "use bluez 5 API" OFF)
 option(xwalk_vehicle_extension "Crosswalk vehicle extension" OFF)
 set(XWALK_EXTENSION_PATH "/automotive-message-broker/xwalk" CACHE PATH "directory the xwalk extension will be installed to")
+set(QMAKE_INSTALL_PATH "/usr/bin/qmake" CACHE PATH "qmake executable path")
 
 #turn on -fpic/-fpie:
 set(CMAKE_POSITION_INDEPENDENT_CODE ON)
index 60138ad..9c4afa8 100644 (file)
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ You will also need to edit your config to enable the Qt-based mainloop:
 
 ~~~~~~~~~~~~~{.json}
 {
-       "mainloop" : "/usr/lib/x86_64-linux-gnu/automotive-message-broker/qtmainloopplugin.so",
+       "mainloop" : "/usr/lib/i386-linux-gnu/automotive-message-broker/qtmainloopplugin.so",
        "plugins" : "/etc/ambd/plugins.d"
 }
 ~~~~~~~~~~~~~
index f829d4f..8427b3b 100644 (file)
@@ -3,11 +3,15 @@ if(bluemonkey_plugin)
 message(STATUS "enabling bluemonkey plugin")
 
 set(qtmainloop ON CACHE INTERNAL "")
+set(CMAKE_PREFIX_PATH "${QMAKE_INSTALL_PATH}")
+
+message(STATUS "using path: ${CMAKE_PREFIX_PATH}")
 
 find_package(Qt5Core REQUIRED)
 find_package(Qt5Network REQUIRED)
 find_package(Qt5Qml REQUIRED)
 if(Qt5Core_FOUND)
+       message(STATUS "qt version: ${QMAKE_INSTALL_PATH}/include/QtCore/${Qt5Core_VERSION}/QtCore")
        set(QT_INCLUDE_DIRS ${Qt5Core_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Qml_INCLUDE_DIRS})
        set(QT_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Network_LIBRARIES} ${Qt5Qml_LIBRARIES})
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
@@ -46,14 +50,16 @@ find_package(Qt5DBus)
 
 if(Qt5DBus_FOUND)
        message(STATUS "enabling dbus bluemonkey module")
-       add_library(bluemonkeyDBusModule MODULE bmdbus.cpp)
+       set(QT_INCLUDE_DIRS ${QT_INCLUDE_DIRS} ${QMAKE_INSTALL_PATH}/include/QtCore/${Qt5Core_VERSION}/QtCore)
+       add_executable(bluemonkeyDBusModule bmdbus.cpp)
        set_target_properties(bluemonkeyDBusModule PROPERTIES PREFIX "")
+       set_target_properties(bluemonkeyDBusModule PROPERTIES SUFFIX ".so")
        target_link_libraries(bluemonkeyDBusModule ${link_libraries} amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${QT_LIBRARIES} ${Qt5DBus_LIBRARIES})
        set(QT_INCLUDE_DIRS ${QT_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS})
-       install(TARGETS bluemonkeyDBusModule LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH})
+       install(TARGETS bluemonkeyDBusModule RUNTIME DESTINATION ${PLUGIN_INSTALL_PATH})
 endif()
 
-include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${communi_INCLUDE_DIRS} ${QT_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common)
+include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${communi_INCLUDE_DIRS} ${QT_INCLUDE_DIRS} ${QT_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common)
 
 set(bluemonkeyplugin_headers bluemonkey.h authenticate.h)
 set(bluemonkeyplugin_sources bluemonkey.cpp authenticate.cpp)
index 1407805..4a21a1b 100644 (file)
@@ -37,7 +37,7 @@
 
 #define foreach Q_FOREACH
 
-typedef std::map<std::string, QObject*> create_bluemonkey_module_t(std::map<std::string, std::string> config, QObject* parent);
+typedef void create_bluemonkey_module_t(std::map<std::string, std::string> config, std::map<std::string, QObject*> &exports, QString &javascript, QObject* parent);
 
 extern "C" void create(AbstractRoutingEngine* routingengine, map<string, string> config)
 {
@@ -292,13 +292,18 @@ bool Bluemonkey::loadModule(QString path)
 
        create_bluemonkey_module_t* create = (create_bluemonkey_module_t*)(c);
 
-       std::map<std::string, QObject*> exports = create(configuration, this);
+       std::map<std::string, QObject*> exports;
+       QString js;
+       create(configuration, exports, js, this);
 
        for(auto i : exports)
        {
-               loadModule(i.first, i.second);
+               QObject* obj = i.second;
+               loadModule(i.first, obj);
        }
 
+       engine->evaluate(js);
+
        return true;
 }
 
@@ -312,9 +317,7 @@ void Bluemonkey::reloadEngine()
        QJSValue value = engine->newQObject(this);
        engine->globalObject().setProperty("bluemonkey", value);
 
-       QThread* thread = new QThread(this);
-
-       engine->moveToThread(thread);
+       //engine->moveToThread(thread);
 
        thread->start();
 
@@ -339,7 +342,7 @@ void Bluemonkey::writeProgram(QString program)
 
        if(!file.open(QIODevice::ReadWrite | QIODevice::Append))
        {
-               DebugOut(DebugOut::Error)<<"failed to open file: "<<file.fileName().toStdString()<<endl;
+               DebugOut(DebugOut::Error) << "failed to open file: " << file.fileName().toStdString() << endl;
                return;
        }
 
@@ -599,6 +602,7 @@ QVariant BluemonkeySink::zonesForProperty(QString prop, QString src)
 Bluemonkey::Bluemonkey(std::map<string, string> config, QObject *parent)
        :QObject(parent), engine(nullptr), configuration(config)
 {
+       thread = new QThread(this);
        QTimer::singleShot(1,this,SLOT(reloadEngine()));
 }
 
@@ -621,3 +625,12 @@ bool Bluemonkey::loadModule(const std::string & name, QObject *module)
                engine->globalObject().setProperty(obj.c_str(), val);
        }
 }
+
+
+void Bluemonkey::assertIsTrue(bool isTrue, const QString & msg)
+{
+       if(!isTrue)
+               log(msg);
+
+       Q_ASSERT(isTrue);
+}
index 67f6bdc..c8a82cd 100644 (file)
@@ -100,6 +100,8 @@ public:
        bool loadModule(const string &name, QObject* module);
 
 public Q_SLOTS:
+       void assertIsTrue(bool isTrue, const QString &msg="");
+
        void loadConfig(QString str);
 
        bool loadModule(QString path);
@@ -118,7 +120,7 @@ Q_SIGNALS:
        void ready();
 
 private:
-
+       QThread* thread;
        QList<void*> modules;
        QJSEngine* engine;
        QStringList configsToLoad;
index 41a3dd1..f8ca281 100644 (file)
 
 #include <QDBusInterface>
 #include <QDBusConnection>
+#include <QDBusReply>
+#include <QCoreApplication>
+#include <QMetaMethod>
 
-extern "C" std::map<std::string, QObject*> create(std::map<std::string, std::string> config, QObject* parent)
+#include "bmdbus_p.h"
+
+extern "C" std::map<std::string, QObject*> create(std::map<std::string, std::string> config, std::map<std::string, QObject*> &exports, QString &js, QObject* parent)
 {
-       std::map<std::string, QObject*> moduleInstances;
-       moduleInstances["dbus"] = new BMDBus(parent);
-       return moduleInstances;
+
+       exports["dbus"] = new BMDBus(parent);
+       exports["testExport"] = new TestQObject(parent);
+
+       js += "dbus.defineMethodSignature = function(obj, methodName, retType, args)"
+                 "{"
+                 "  metadata = obj['_metadata'];"
+                 "  if(!metadata)"
+                 "    metadata = new Object;"
+                 "  metadata[methodName] = {'retType' : retType, 'signature' : args};"
+                 "  obj['_metadata'] = metadata;"
+                 "}";
+
 }
 
 BMDBus::BMDBus(QObject *parent)
@@ -38,19 +53,218 @@ BMDBus::BMDBus(QObject *parent)
 
 QObject *BMDBus::createInterface(const QString &service, const QString &path, const QString &interface, BMDBus::Connection bus)
 {
-       return new QDBusInterface(service, path, interface, bus == Session ? QDBusConnection::sessionBus() : QDBusConnection::systemBus(), this);
+       return new QDBusInterface(service, path, interface, getConnection(bus), this);
 }
 
+bool BMDBus::registerService(const QString &service, BMDBus::Connection bus)
+{
+       QDBusConnection con = getConnection(bus);
+
+       return con.registerService(service);
+}
 
-bool BMDBus::exportObject(const QString &path, const QString &interface, BMDBus::Connection bus, QObject * object)
+bool BMDBus::unregisterService(const QString &service, BMDBus::Connection bus)
 {
-       QDBusConnection con = bus == Session ? QDBusConnection::sessionBus( ): QDBusConnection::systemBus();
+       QDBusConnection con = getConnection(bus);
+
+       return con.unregisterService(service);
+}
 
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
-       con.registerObject(path, interface, object, QDBusConnection::ExportAllContents);
+
+bool BMDBus::exportObject(const QString &path, const QString &interface, BMDBus::Connection bus, const QJSValue &object)
+{
+       if(!object.isObject())
+               return false;
+/*
+       QDBusConnection con = getConnection(bus);
+/// TODO: should be qt 5.5:
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 1))
+       return con.registerObject(path, interface, object, QDBusConnection::ExportAllContents);
 #else
        DebugOut(DebugOut::Warning) << "BMDBus::exportObject() interface is ignored in qt 5.4 and lower" << endl;
-       con.registerObject(path, object, QDBusConnection::ExportAllContents);
+       return con.registerObject(path, object, QDBusConnection::ExportAllContents);
 #endif
+*/
+}
+
+QString BMDBus::errorMessage(const BMDBus::Connection bus)
+{
+       QDBusConnection con = getConnection(bus);
+
+       QDBusError err = con.lastError();
+
+       return err.name() + "(" +QString::number(err.type()) + ") : " + err.message();
+}
+
+QDBusConnection BMDBus::getConnection(const BMDBus::Connection bus)
+{
+       QDBusConnection con = bus == BMDBus::Session ? QDBusConnection::sessionBus() : QDBusConnection::systemBus();
+
+       return con;
+}
+
+
+
+BluemonkeyQObjectPrivate::BluemonkeyQObjectPrivate(BluemonkeyQObject *iface)
+{
+
+}
+
+QVariant BluemonkeyQObjectPrivate::property(const QByteArray &property)
+{
+
+}
+
+bool BluemonkeyQObjectPrivate::setProperty(const QByteArray &property, const QVariant &value)
+{
+
+}
+
+void BluemonkeyQObjectPrivate::createFrom(const QJSValue &value)
+{
+       if(!value.isObject() || !value.hasProperty("_metadata"))
+       {
+               DebugOut(DebugOut::Warning) << "No metadata or not object" << endl;
+               return;
+       }
+
+       QVariantMap metaData = value.property("_metadata").toVariant().toMap();
+
+       Q_FOREACH(QString key, metaData.keys())
+       {
+               QString methodName = key;
+               QVariantMap metaMethod = metaData[key].toMap();
+
+               QStringList args = metaMethod["args"].toStringList();
+               QString returnType = metaMethod["retType"].toString();
+               metaObject->addMethod();
+       }
+
+}
+
 
+BluemonkeyMetaObject::BluemonkeyMetaObject(BluemonkeyQObject *qq, BluemonkeyQObjectPrivate *dd, const QMetaObject *mo)
+       :q(qq), d(dd)
+{
+       m_builder.setSuperClass(mo);
+       m_builder.setClassName(mo->className());
+       m_builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+
+       m_metaObject = m_builder.toMetaObject();
+
+       QObjectPrivate* op = QObjectPrivate::get(q);
+       m_parent = static_cast<QAbstractDynamicMetaObject*>(op->metaObject);
+       *static_cast<QMetaObject*>(this) = *m_metaObject;
+       op->metaObject = this;
+}
+
+BluemonkeyMetaObject::~BluemonkeyMetaObject()
+{
+       delete m_metaObject;
+}
+
+void BluemonkeyMetaObject::updateProperties(const QVariantMap &data)
+{
+       Q_FOREACH(QString key, data.keys())
+       {
+               int i = m_propertyIdLookup.value(key.toUtf8());
+               activate(q, i + m_metaObject->methodOffset(), 0);
+       }
+}
+
+void BluemonkeyMetaObject::addProperty(const QByteArray& name, const QJSValue& property)
+{
+       int id = m_builder.propertyCount();
+       m_builder.addSignal("__"+QByteArray::number(id)+"()");
+       m_propertyIdLookup.insert(name, id);
+       QMetaType::Type propertyType = jsType(property);
+       m_propertyTypeLookup.insert(name, propertyType);
+}
+
+void BluemonkeyMetaObject::addMethod(const QByteArray& name, const QString & returnType, const QStringList &args)
+{
+       if(!method.isCallable()) return;
+
+       if(returnType.isEmpty())
+               returnType = "void";
+
+
+}
+
+QMetaType::Type BluemonkeyMetaObject::jsType(const QJSValue &value)
+{
+       int type = 0;
+       if(value.isArray())
+       {
+               type = qMetaTypeId<QVariantList>();
+       }
+       else if(value.isBool())
+       {
+               type = qMetaTypeId<bool>();
+       }
+       else if(value.isDate())
+       {
+               type = qMetaTypeId<QDateTime>();
+       }
+       else if(value.isNumber())
+       {
+               type = qMetaTypeId<double>();
+       }
+       else if(value.isObject())
+       {
+               type = qMetaTypeId<BluemonkeyQObject*>();
+       }
+       else if(value.isQObject())
+       {
+               type = qMetaTypeId<QObject*>();
+       }
+       else if(value.isString())
+       {
+               type = qMetaTypeId<QString>();
+       }
+       else if(value.isVariant())
+       {
+               type = qMetaTypeId<QVariant>();
+       }
+}
+
+int BluemonkeyMetaObject::metaCall(QMetaObject::Call _c, int _id, void **_a)
+{
+
+}
+
+int BluemonkeyMetaObject::createProperty(const char *, const char *)
+{
+
+}
+
+
+BluemonkeyQObject::BluemonkeyQObject(QObject *parent)
+       :QObject(*new BluemonkeyQObjectPrivate(this), parent)
+{
+       Q_D(BluemonkeyQObject);
+       d->metaObject = new BluemonkeyMetaObject(this, d, metaObject());
+}
+
+int main(int argc, char** argv)
+{
+       DebugOut::setDebugThreshhold(7);
+
+       DebugOut() << "Started BMDBus test " PROJECT_VERSION << endl;
+
+       QCoreApplication app(argc, argv);
+
+       BMDBus dbus;
+
+       dbus.registerService("org.bluemonkey.test", BMDBus::Session);
+/*     dbus.exportObject("/testQObject", "org.awesome.interface", BMDBus::Session, new TestQObject(&dbus));
+       dbus.exportObject("/bareQObject", "org.awesome.interface2", BMDBus::Session, new BareQObject());
+
+       QDBusInterface* iface = static_cast<QDBusInterface*>(dbus.createInterface("org.bluemonkey.test", "/testQObject", "org.awesome.interface", BMDBus::Session));
+
+       QDBusReply<QString> reply = iface->call("awesomeMethod");
+
+       DebugOut() << "Reply value: " << reply.value().toStdString() << endl;
+*/
+       app.exec();
 }
index 7b4dbeb..47256c4 100644 (file)
 #define BM_DBUS_H_
 
 #include <QObject>
+#include <QJSValue>
+#include <QDBusConnection>
 
 class BMDBus : public QObject
 {
        Q_OBJECT
-       Q_ENUMS(Connection)
+       Q_PROPERTY(int Session READ sessionBus)
+       Q_PROPERTY(int System READ systemBus)
 
 public:
 
        enum Connection{
-               System,
+               System=0,
                Session
        };
 
+       Q_ENUMS(Connection)
+
        BMDBus(QObject * parent = nullptr);
 
+       Connection sessionBus() { return BMDBus::Session; }
+       Connection systemBus() { return BMDBus::System; }
+
 public Q_SLOTS:
 
        QObject* createInterface(const QString & service, const QString & path, const QString & interface, Connection bus);
 
-       bool exportObject(const QString & path, const QString & interface, Connection bus, QObject *obj);
+       bool registerService(const QString & service, Connection bus);
+
+       bool unregisterService(const QString & service, Connection bus);
+
+       bool exportObject(const QString & path, const QString & interface, Connection bus, const QJSValue &obj);
+
+       QJSValue defineMethodSignature(const QJSValue & obj, const QString & methodName, const QString & returnType, const QStringList & arguments);
+
+       QString errorMessage(const Connection bus = Session);
 
 private: ///methods:
 
+       QDBusConnection getConnection(const Connection bus);
+};
+
+class BluemonkeyQObjectPrivate;
+class BluemonkeyQObject : public QObject
+{
+       Q_OBJECT
+public:
+       BluemonkeyQObject(QObject* parent = nullptr);
+
+private:
+       Q_DECLARE_PRIVATE(BluemonkeyQObject)
+       Q_DISABLE_COPY(BluemonkeyQObject)
+};
+
+Q_DECLARE_METATYPE(BluemonkeyQObject*)
 
+class BareQObject : public QObject
+{
+       Q_OBJECT
+public Q_SLOTS:
+       void becauseImHappy() { }
 };
 
+class TestQObject : public QObject
+{
+       Q_OBJECT
+public:
+       TestQObject(QObject * parent = nullptr) : QObject(parent) {}
+public Q_SLOTS:
+       QString awesomeMethod() { return "awesome"; }
+};
 
 #endif
diff --git a/plugins/bluemonkey/bmdbus_p.h b/plugins/bluemonkey/bmdbus_p.h
new file mode 100644 (file)
index 0000000..aa50eba
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef _BMDBUS_P_H_
+#define _BMDBUS_P_H_
+
+#include <QJSValue>
+#include <QHash>
+
+#include <private/qobject_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+
+class BluemonkeyQObject;
+class BluemonkeyMetaObject;
+class BluemonkeyQObjectPrivate : public QObjectPrivate
+{
+public:
+       BluemonkeyQObjectPrivate(BluemonkeyQObject* iface);
+
+       virtual ~BluemonkeyQObjectPrivate() {}
+
+       QVariant property(const QByteArray& property);
+       bool setProperty(const QByteArray& property, const QVariant& value);
+
+       void createFrom(const QJSValue & value);
+
+       BluemonkeyQObject* q;
+       BluemonkeyMetaObject* metaObject;
+};
+
+class BluemonkeyMetaObject : public QAbstractDynamicMetaObject
+{
+public:
+       BluemonkeyMetaObject(BluemonkeyQObject* qq, BluemonkeyQObjectPrivate* dd,
+                                                const QMetaObject* mo);
+       ~BluemonkeyMetaObject();
+
+       void updateProperties(const QVariantMap & data);
+
+private:
+       void addProperty(const QByteArray & name, const QJSValue & property);
+       void addMethod(const QByteArray & name, const QString &returnType, const QStringList &args);
+
+       QMetaType::Type jsType(const QJSValue& value);
+
+protected:
+       virtual int metaCall(QMetaObject::Call _c, int _id, void** _a);
+       virtual int createProperty(const char *, const char *);
+
+private:
+       BluemonkeyQObject *q;
+       BluemonkeyQObjectPrivate *d;
+
+       QMetaObjectBuilder m_builder;
+       QMetaObject* m_metaObject;
+       QAbstractDynamicMetaObject* m_parent;
+
+       int m_propertyOffset;
+       int m_methodOffset;
+
+       QHash<QByteArray, int> m_propertyIdLookup;
+       QHash<QByteArray, QMetaType::Type> m_propertyTypeLookup;
+       QHash<QByteArray, int> m_methodIdLookup;
+
+       friend class BluemonkeyQObjectPrivate;
+};
+
+#endif
index 14df87e..7cc0b20 100644 (file)
@@ -20,22 +20,66 @@ amb.createCustomProperty("AnswerToTheUniverse", 42);
 dbusConnected = amb.subscribeTo("DBusConnected");
 
 dbusConnected.changed.connect(function () {
-    if(dbusConnected.value !== true)
-        return;
+       if(dbusConnected.value !== true)
+               return;
 
-    amb.exportInterface("Bluemonkey",[{'BluemonkeySuperProperty' : 'SuperProperty'},
-                               {'AnswerToTheUniverse' : 'AnswerToTheUniverse'}]);
+       amb.exportInterface("Bluemonkey",[{'BluemonkeySuperProperty' : 'SuperProperty'},
+                                                          {'AnswerToTheUniverse' : 'AnswerToTheUniverse'}]);
 });
 
 bluemonkey.loadModule("@PLUGIN_INSTALL_PATH@/bluemonkeyDBusModule.so");
 
+exportObj = bluemonkey.createQObject();
+exportObj.foo = function() { return "bar"; }
+exportObj.bar = true;
+
+testExport.jsFunc = function() { return "js rules!"; }
+
 if(dbus)
 {
-    var dbusIface = dbus.createInterface("org.freedesktop.DBus", "/", "org.freedesktop.DBus", dbus.Session);
+       try
+       {
+               var dbusIface = dbus.createInterface("org.freedesktop.DBus", "/", "org.freedesktop.DBus", dbus.Session);
+
+               var reply = dbusIface.GetId();
+
+               bluemonkey.log("org.freedesktop.DBus.GetId() response: " + reply);
+
+               var registered = dbus.registerService("org.bluemonkey", dbus.Session)
+
+               bluemonkey.assertIsTrue(registered, "could not register service: " + dbus.errorMessage(dbus.Session));
+
+               for(prop in exportObj)
+               {
+                       bluemonkey.log(prop +"="+ exportObj[prop]);
+               }
+               for(prop in testExport)
+               {
+                       bluemonkey.log(prop +"="+ testExport[prop]);
+               }
+
+               var exported = dbus.exportObject("/one", "org.awesome.interface", dbus.Session, exportObj);
+               bluemonkey.log("exported: " + exported)
+
+               bluemonkey.assertIsTrue(exported, "Failed to export custom dbus object: " + dbus.errorMessage(dbus.Session));
+
+               var exported2 = dbus.exportObject("/two", "org.awesome.interface2", dbus.Session, testExport)
+               bluemonkey.log("exported2: " + exported2)
+
+               bluemonkey.assertIsTrue(exported2, "failed to export testExport: " + dbus.errorMessage());
+
+               //var exportedIface = dbus.createInterface("org.bluemonkey", "/", "org.awesome.interface", dbus.Session);
+
+               //bluemonkey.assertIsTrue(exportedIface.foo, "member 'foo' is missing " + dbus.errorMessage());
 
-    var reply = dbusIface.GetId();
+               //var reply = exportedIface.foo();
 
-    bluemonkey.log("org.freedesktop.DBus.GetId() response: " + reply);
+               //bluemonkey.assertIsTrue(reply === "bar" && exportedIface.bar === true);
+       }
+       catch(error)
+       {
+               bluemonkey.log("nasty dbus errors");
+       }
 }
 
 amb.createCustomProperty("VehicleSpeed", 10);