upgrade obexd to 0.47
[profile/ivi/obexd.git] / client / opp.c
index be382ef..5137de8 100644 (file)
 #include <config.h>
 #endif
 
+#include <errno.h>
+#include <gdbus.h>
+
 #include "log.h"
 
+#include "transfer.h"
 #include "session.h"
 #include "driver.h"
 #include "opp.h"
 
 #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
+#define OPP_INTERFACE "org.bluez.obex.ObjectPush"
+#define ERROR_INTERFACE "org.bluez.obex.Error"
+
+struct opp_data {
+       struct obc_session *session;
+};
+
+static DBusConnection *conn = NULL;
+
+static DBusMessage *opp_send_file(DBusConnection *connection,
+                                       DBusMessage *message, void *user_data)
+{
+       struct opp_data *opp = user_data;
+       struct obc_transfer *transfer;
+       DBusMessage *reply;
+       char *filename;
+       char *basename;
+       GError *err = NULL;
+
+       if (dbus_message_get_args(message, NULL,
+                                       DBUS_TYPE_STRING, &filename,
+                                       DBUS_TYPE_INVALID) == FALSE)
+               return g_dbus_create_error(message,
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
+
+       basename = g_path_get_basename(filename);
+
+       transfer = obc_transfer_put(NULL, basename, filename, NULL, 0, &err);
+
+       g_free(basename);
+
+       if (transfer == NULL)
+               goto fail;
+
+       if (!obc_session_queue(opp->session, transfer, NULL, NULL, &err))
+               goto fail;
+
+       return obc_transfer_create_dbus_reply(transfer, message);
+
+fail:
+       reply = g_dbus_create_error(message,
+                               ERROR_INTERFACE ".Failed", "%s", err->message);
+       g_error_free(err);
+       return reply;
+}
+
+static DBusMessage *opp_pull_business_card(DBusConnection *connection,
+                                       DBusMessage *message, void *user_data)
+{
+       struct opp_data *opp = user_data;
+       struct obc_transfer *pull;
+       DBusMessage *reply;
+       const char *filename = NULL;
+       GError *err = NULL;
+
+       if (dbus_message_get_args(message, NULL,
+                               DBUS_TYPE_STRING, &filename,
+                               DBUS_TYPE_INVALID) == FALSE)
+               return g_dbus_create_error(message,
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
+
+       pull = obc_transfer_get("text/x-vcard", NULL, filename, &err);
+       if (pull == NULL)
+               goto fail;
+
+       if (!obc_session_queue(opp->session, pull, NULL, NULL, &err))
+               goto fail;
+
+       return obc_transfer_create_dbus_reply(pull, message);
+
+fail:
+       reply = g_dbus_create_error(message,
+                               ERROR_INTERFACE ".Failed", "%s", err->message);
+       g_error_free(err);
+       return reply;
+}
+
+static DBusMessage *opp_exchange_business_cards(DBusConnection *connection,
+                                       DBusMessage *message, void *user_data)
+{
+       return g_dbus_create_error(message, ERROR_INTERFACE ".Failed", NULL);
+}
+
+static const GDBusMethodTable opp_methods[] = {
+       { GDBUS_METHOD("SendFile",
+               GDBUS_ARGS({ "sourcefile", "s" }),
+               GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
+               opp_send_file) },
+       { GDBUS_METHOD("PullBusinessCard",
+               GDBUS_ARGS({ "targetfile", "s" }),
+               GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
+               opp_pull_business_card) },
+       { GDBUS_METHOD("ExchangeBusinessCards",
+               GDBUS_ARGS({ "clientfile", "s" }, { "targetfile", "s" }),
+               GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
+               opp_exchange_business_cards) },
+       { }
+};
+
+static void opp_free(void *data)
+{
+       struct opp_data *opp = data;
+
+       obc_session_unref(opp->session);
+       g_free(opp);
+}
+
+static int opp_probe(struct obc_session *session)
+{
+       struct opp_data *opp;
+       const char *path;
+
+       path = obc_session_get_path(session);
+
+       DBG("%s", path);
+
+       opp = g_try_new0(struct opp_data, 1);
+       if (!opp)
+               return -ENOMEM;
+
+       opp->session = obc_session_ref(session);
+
+       if (!g_dbus_register_interface(conn, path, OPP_INTERFACE, opp_methods,
+                                               NULL, NULL, opp, opp_free)) {
+               opp_free(opp);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void opp_remove(struct obc_session *session)
+{
+       const char *path = obc_session_get_path(session);
+
+       DBG("%s", path);
+
+       g_dbus_unregister_interface(conn, path, OPP_INTERFACE);
+}
 
 static struct obc_driver opp = {
        .service = "OPP",
        .uuid = OPP_UUID,
+       .probe = opp_probe,
+       .remove = opp_remove
 };
 
 int opp_init(void)
 {
+       int err;
+
        DBG("");
 
-       return obc_driver_register(&opp);
+       conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+       if (!conn)
+               return -EIO;
+
+       err = obc_driver_register(&opp);
+       if (err < 0) {
+               dbus_connection_unref(conn);
+               conn = NULL;
+               return err;
+       }
+
+       return 0;
 }
 
 void opp_exit(void)
 {
        DBG("");
 
+       dbus_connection_unref(conn);
+       conn = NULL;
+
        obc_driver_unregister(&opp);
 }