#13795: Initial commit for sflphone-android
includes: libexpat libyaml libdbus-c++ commoncpp ccrtp
libdbus (from android-4.0.4 sources)
TODO:
- git ignores "/jni/sflphone", sflphone repo should be cloned.
- sflphone-android only needs daemon directory. Ideally it should be possible
to clone it without cloning the whole sflphone project.
into sfl-android (commit 6a0fa7a "#13961: Fix cipher handling" has been used here)
- add pjsip-android project as a git submodule
- sflphone-android needs pjsip android project. Ideally daemon git repository
should not embed pjsip. Instead pjsip should be clone from official repositories.
Considering this, structure should have three distincts git repos:
sflphone-android/.git
sflphone-android/jni/ccrtp-1.8.0-android
sflphone-android/jni/commoncpp2-1.8.1-android
sflphone-android/jni/dbus
sflphone-android/jni/libdbus-c++-0.9.0-android
sflphone-android/jni/libexpat
sflphone-android/jni/libyaml
sflphone-android/jni/sflphone-daemon/.git
sflphone-android/jni/sflphone-daemon/src/audio
sflphone-android/jni/sflphone-daemon/src/config
sflphone-android/jni/sflphone-daemon/src/dbus
sflphone-android/jni/sflphone-daemon/src/history
sflphone-android/jni/sflphone-daemon/src/hooks
sflphone-android/jni/sflphone-daemon/src/iax
sflphone-android/jni/sflphone-daemon/src/sip
sflphone-android/jni/sflphone-daemon/src/video
sflphone-android/jni/pjsip-android/.git
Signed-off-by: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
diff --git a/jni/libdbus-c++-0.9.0-android/src/object.cpp b/jni/libdbus-c++-0.9.0-android/src/object.cpp
new file mode 100644
index 0000000..96e20ba
--- /dev/null
+++ b/jni/libdbus-c++-0.9.0-android/src/object.cpp
@@ -0,0 +1,385 @@
+/*
+ *
+ * D-Bus++ - C++ bindings for D-Bus
+ *
+ * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus-c++/debug.h>
+#include <dbus-c++/object.h>
+#include "internalerror.h"
+
+#include <cstring>
+#include <map>
+#include <dbus/dbus.h>
+
+#include "message_p.h"
+#include "server_p.h"
+#include "connection_p.h"
+
+using namespace DBus;
+
+Object::Object(Connection &conn, const Path &path, const char *service)
+ : _conn(conn), _path(path), _service(service ? service : ""), _default_timeout(-1)
+{
+}
+
+Object::~Object()
+{
+}
+
+void Object::set_timeout(int new_timeout)
+{
+ debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout);
+ if (new_timeout < 0 && new_timeout != -1)
+ throw ErrorInvalidArgs("Bad timeout, cannot set it");
+ _default_timeout = new_timeout;
+}
+
+struct ObjectAdaptor::Private
+{
+ static void unregister_function_stub(DBusConnection *, void *);
+ static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *);
+};
+
+static DBusObjectPathVTable _vtable =
+{
+ ObjectAdaptor::Private::unregister_function_stub,
+ ObjectAdaptor::Private::message_function_stub,
+ NULL, NULL, NULL, NULL
+};
+
+void ObjectAdaptor::Private::unregister_function_stub(DBusConnection *conn, void *data)
+{
+ //TODO: what do we have to do here ?
+}
+
+DBusHandlerResult ObjectAdaptor::Private::message_function_stub(DBusConnection *, DBusMessage *dmsg, void *data)
+{
+ ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data);
+
+ if (o)
+ {
+ Message msg(new Message::Private(dmsg));
+
+ debug_log("in object %s", o->path().c_str());
+ debug_log(" got message #%d from %s to %s",
+ msg.serial(),
+ msg.sender(),
+ msg.destination()
+ );
+
+ return o->handle_message(msg)
+ ? DBUS_HANDLER_RESULT_HANDLED
+ : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ else
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+}
+
+typedef std::map<Path, ObjectAdaptor *> ObjectAdaptorTable;
+static ObjectAdaptorTable _adaptor_table;
+
+ObjectAdaptor *ObjectAdaptor::from_path(const Path &path)
+{
+ ObjectAdaptorTable::iterator ati = _adaptor_table.find(path);
+
+ if (ati != _adaptor_table.end())
+ return ati->second;
+
+ return NULL;
+}
+
+ObjectAdaptorPList ObjectAdaptor::from_path_prefix(const std::string &prefix)
+{
+ ObjectAdaptorPList ali;
+
+ ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
+
+ size_t plen = prefix.length();
+
+ while (ati != _adaptor_table.end())
+ {
+ if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
+ ali.push_back(ati->second);
+
+ ++ati;
+ }
+
+ return ali;
+}
+
+ObjectPathList ObjectAdaptor::child_nodes_from_prefix(const std::string &prefix)
+{
+ ObjectPathList ali;
+
+ ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
+
+ size_t plen = prefix.length();
+
+ while (ati != _adaptor_table.end())
+ {
+ if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
+ {
+ std::string p = ati->second->path().substr(plen);
+ p = p.substr(0, p.find('/'));
+ ali.push_back(p);
+ }
+ ++ati;
+ }
+
+ ali.sort();
+ ali.unique();
+
+ return ali;
+}
+
+ObjectAdaptor::ObjectAdaptor(Connection &conn, const Path &path)
+ : Object(conn, path, conn.unique_name())
+{
+ register_obj();
+}
+
+ObjectAdaptor::~ObjectAdaptor()
+{
+ unregister_obj(false);
+}
+
+void ObjectAdaptor::register_obj()
+{
+ debug_log("registering local object %s", path().c_str());
+
+ if (!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this))
+ {
+ throw ErrorNoMemory("unable to register object path");
+ }
+
+ _adaptor_table[path()] = this;
+}
+
+void ObjectAdaptor::unregister_obj(bool)
+{
+ _adaptor_table.erase(path());
+
+ debug_log("unregistering local object %s", path().c_str());
+
+ dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str());
+}
+
+void ObjectAdaptor::_emit_signal(SignalMessage &sig)
+{
+ sig.path(path().c_str());
+
+ conn().send(sig);
+}
+
+struct ReturnLaterError
+{
+ const Tag *tag;
+};
+
+bool ObjectAdaptor::handle_message(const Message &msg)
+{
+ switch (msg.type())
+ {
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ {
+ const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg);
+ const char *member = cmsg.member();
+ const char *interface = cmsg.interface();
+
+ debug_log(" invoking method %s.%s", interface, member);
+
+ InterfaceAdaptor *ii = find_interface(interface);
+ if (ii)
+ {
+ try
+ {
+ Message ret = ii->dispatch_method(cmsg);
+ conn().send(ret);
+ }
+ catch (Error &e)
+ {
+ ErrorMessage em(cmsg, e.name(), e.message());
+ conn().send(em);
+ }
+ catch (ReturnLaterError &rle)
+ {
+ _continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag);
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ default:
+ {
+ return false;
+ }
+ }
+}
+
+void ObjectAdaptor::return_later(const Tag *tag)
+{
+ ReturnLaterError rle = { tag };
+ throw rle;
+}
+
+void ObjectAdaptor::return_now(Continuation *ret)
+{
+ ret->_conn.send(ret->_return);
+
+ ContinuationMap::iterator di = _continuations.find(ret->_tag);
+
+ delete di->second;
+
+ _continuations.erase(di);
+}
+
+void ObjectAdaptor::return_error(Continuation *ret, const Error error)
+{
+ ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message()));
+
+ ContinuationMap::iterator di = _continuations.find(ret->_tag);
+
+ delete di->second;
+
+ _continuations.erase(di);
+}
+
+ObjectAdaptor::Continuation *ObjectAdaptor::find_continuation(const Tag *tag)
+{
+ ContinuationMap::iterator di = _continuations.find(tag);
+
+ return di != _continuations.end() ? di->second : NULL;
+}
+
+ObjectAdaptor::Continuation::Continuation(Connection &conn, const CallMessage &call, const Tag *tag)
+ : _conn(conn), _call(call), _return(_call), _tag(tag)
+{
+ _writer = _return.writer(); //todo: verify
+}
+
+/*
+*/
+
+ObjectProxy::ObjectProxy(Connection &conn, const Path &path, const char *service)
+ : Object(conn, path, service)
+{
+ register_obj();
+}
+
+ObjectProxy::~ObjectProxy()
+{
+ unregister_obj(false);
+}
+
+void ObjectProxy::register_obj()
+{
+ debug_log("registering remote object %s", path().c_str());
+
+ _filtered = new Callback<ObjectProxy, bool, const Message &>(this, &ObjectProxy::handle_message);
+
+ conn().add_filter(_filtered);
+
+ InterfaceProxyTable::const_iterator ii = _interfaces.begin();
+ while (ii != _interfaces.end())
+ {
+ std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
+ conn().add_match(im.c_str());
+ ++ii;
+ }
+}
+
+void ObjectProxy::unregister_obj(bool throw_on_error)
+{
+ debug_log("unregistering remote object %s", path().c_str());
+
+ InterfaceProxyTable::const_iterator ii = _interfaces.begin();
+ while (ii != _interfaces.end())
+ {
+ std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
+ conn().remove_match(im.c_str(), throw_on_error);
+ ++ii;
+ }
+ conn().remove_filter(_filtered);
+}
+
+Message ObjectProxy::_invoke_method(CallMessage &call)
+{
+ if (call.path() == NULL)
+ call.path(path().c_str());
+
+ if (call.destination() == NULL)
+ call.destination(service().c_str());
+
+ return conn().send_blocking(call, get_timeout());
+}
+
+bool ObjectProxy::_invoke_method_noreply(CallMessage &call)
+{
+ if (call.path() == NULL)
+ call.path(path().c_str());
+
+ if (call.destination() == NULL)
+ call.destination(service().c_str());
+
+ return conn().send(call);
+}
+
+bool ObjectProxy::handle_message(const Message &msg)
+{
+ switch (msg.type())
+ {
+ case DBUS_MESSAGE_TYPE_SIGNAL:
+ {
+ const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg);
+ const char *interface = smsg.interface();
+ const char *member = smsg.member();
+ const char *objpath = smsg.path();
+
+ if (objpath != path()) return false;
+
+ debug_log("filtered signal %s(in %s) from %s to object %s",
+ member, interface, msg.sender(), objpath);
+
+ InterfaceProxy *ii = find_interface(interface);
+ if (ii)
+ {
+ return ii->dispatch_signal(smsg);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ default:
+ {
+ return false;
+ }
+ }
+}