From dcf133afff0f796a6ac00e0b2189e03311fee540 Mon Sep 17 00:00:00 2001 From: Amarnath Valluri Date: Fri, 11 Oct 2013 15:29:58 +0300 Subject: [PATCH] fixes to daemon. initial implementation of client library --- Makefile.am | 2 +- common/Makefile.am | 32 +++ common/log.h | 12 + .../org.tizen.messageport.Manager.xml | 4 +- .../org.tizen.messageport.Service.xml | 6 +- configure.ac | 32 ++- daemon/Makefile.am | 25 +- ...nager-doc-gen-org.tizen.messageport.Manager.xml | 69 ----- daemon/dbus-manager.c | 32 ++- daemon/dbus-server.c | 8 +- daemon/dbus-service.c | 34 ++- daemon/dbus-service.h | 9 +- daemon/manager.c | 70 +++--- daemon/manager.h | 13 +- examples/Makefile.am | 8 + examples/test-app.c | 95 +++++++ lib/Makefile.am | 30 +++ lib/message-port.c | 64 ++--- lib/message-port.h | 8 +- lib/msgport-manager.c | 279 ++++++++++++++++----- lib/msgport-manager.h | 47 +++- lib/msgport-service.c | 165 ++++++++++++ lib/msgport-service.h | 44 ++++ lib/msgport-utils.c | 53 ++++ lib/msgport-utils.h | 10 + 25 files changed, 879 insertions(+), 272 deletions(-) create mode 100644 common/Makefile.am create mode 100644 common/log.h rename {daemon => common}/org.tizen.messageport.Manager.xml (86%) rename {daemon => common}/org.tizen.messageport.Service.xml (73%) delete mode 100644 daemon/dbus-manager-doc-gen-org.tizen.messageport.Manager.xml create mode 100644 examples/Makefile.am create mode 100644 examples/test-app.c create mode 100644 lib/Makefile.am create mode 100644 lib/msgport-service.c create mode 100644 lib/msgport-service.h create mode 100644 lib/msgport-utils.c create mode 100644 lib/msgport-utils.h diff --git a/Makefile.am b/Makefile.am index 05f0939..03ccf40 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = daemon +SUBDIRS = common daemon lib examples ACLOCAL_AMFLAGS = -I m4 diff --git a/common/Makefile.am b/common/Makefile.am new file mode 100644 index 0000000..e04aab7 --- /dev/null +++ b/common/Makefile.am @@ -0,0 +1,32 @@ +lib_LTLIBRARIES = libmessageport-dbus-glue.la +NULL = + +dbus-manager-glue.c dbus-maanager-glue.h : org.tizen.messageport.Manager.xml + $(AM_V_GEM)gdbus-codegen \ + --interface-prefix org.tizen.messageport \ + --c-namespace MsgPort_Dbus_Glue \ + --generate-c-code dbus-manager-glue \ + $< + +dbus-service-glue.c dbus-service-glue.h : org.tizen.messageport.Service.xml + $(AM_V_GEM)gdbus-codegen \ + --interface-prefix org.tizen.messageport \ + --c-namespace MsgPort_Dbus_Glue \ + --generate-c-code dbus-service-glue \ + $< + +nodist_libmessageport_dbus_glue_la_SOURCES = \ + dbus-manager-glue.h \ + dbus-manager-glue.c \ + dubs-service-glue.h \ + dbus-service-glue.c \ + $(NULL) + +libmessageport_dbus_glue_la_CPPFLAGS = \ + -I$(top_builddir) \ + $(GLIB_CFLAGS) $(GIO_CFLAGS) $(GIOUNIX_CFLAGS) + +libmessageport_dbus_glue_la_LIBADD = \ + $(GLIB_LIBS) $(GIO_LIBS) $(GIOUNIX_LIBS) + +CLEANFILES = diff --git a/common/log.h b/common/log.h new file mode 100644 index 0000000..7a03123 --- /dev/null +++ b/common/log.h @@ -0,0 +1,12 @@ +#ifndef _MSGPORT_LOG_H +#define _MSGPORT_LOG_H + +#include + +#define LOG(log_func, frmt, args...) log_func("%s +%d:"frmt, __FILE__, __LINE__, ##args) + +#define DBG(frmt, args...) LOG(g_debug, frmt, ##args) +#define WARN(frmt, args...) LOG(g_warning, frmt, ##args) +#define ERR(frmt, args...) LOG(g_error, frmt, ##args) + +#endif /* _MSGPORT_LOG_H */ diff --git a/daemon/org.tizen.messageport.Manager.xml b/common/org.tizen.messageport.Manager.xml similarity index 86% rename from daemon/org.tizen.messageport.Manager.xml rename to common/org.tizen.messageport.Manager.xml index c3027da..850ecb5 100644 --- a/daemon/org.tizen.messageport.Manager.xml +++ b/common/org.tizen.messageport.Manager.xml @@ -10,10 +10,10 @@ - + - + diff --git a/daemon/org.tizen.messageport.Service.xml b/common/org.tizen.messageport.Service.xml similarity index 73% rename from daemon/org.tizen.messageport.Service.xml rename to common/org.tizen.messageport.Service.xml index 406af98..0457af4 100644 --- a/daemon/org.tizen.messageport.Service.xml +++ b/common/org.tizen.messageport.Service.xml @@ -6,12 +6,14 @@ - + - + + + diff --git a/configure.ac b/configure.ac index 65250fb..7dc2b62 100644 --- a/configure.ac +++ b/configure.ac @@ -9,17 +9,31 @@ AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.11 nostdinc silent-rules subdir-objects tar-pax -Wno-portability]) +LT_INIT([disable-static]) # Checks for programs. AC_PROG_CC # Checks for libraries. -PKG_CHECK_MODULES([MESSAGEPORT], - [glib-2.0 >= 2.30 - gio-2.0 - gio-unix-2.0]) -AC_SUBST(MESSAGEPORT_CFLAGS) -AC_SUBST(MESSAGEPORT_LIBS) +PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.30]) +AC_SUBST(GLIB_CFLAGS) +AC_SUBST(GLIB_LIBS) + +PKG_CHECK_MODULES([GIO],[gio-2.0]) +AC_SUBST(GIO_CFLAGS) +AC_SUBST(GIO_LIBS) + +PKG_CHECK_MODULES([GIOUNIX],[gio-unix-2.0]) +AC_SUBST(GIOUNIX_CFLAGS) +AC_SUBST(GIOUINX_LIBS) + +PKG_CHECK_MODULES([BUNDLE], [bundle]) +AC_SUBST(BUNDLE_CFLAGS) +AC_SUBST(BUNDLE_LIBS) + +AC_DEFINE(MESSAGEPORT_BUS_ADDRESS, + ["unix:path=%s/.message-port", g_get_user_runtime_dir()], + [messageport daemon server socket address]) # Checks for header files. AC_CHECK_HEADERS([string.h]) @@ -30,4 +44,8 @@ AC_CHECK_HEADERS([string.h]) AC_OUTPUT([ Makefile -daemon/Makefile]) +common/Makefile +daemon/Makefile +lib/Makefile +examples/Makefile +]) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 57c1854..42507df 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -1,25 +1,7 @@ bin_PROGRAMS = messageportd NULL = -dbus-manager-glue.c dbus-maanager-glue.h : org.tizen.messageport.Manager.xml - gdbus-codegen \ - --interface-prefix org.tizen.messageport \ - --c-namespace MsgPort_Dbus_Glue \ - --generate-c-code dbus-manager-glue \ - $< - -dbus-service-glue.c dbus-service-glue.h : org.tizen.messageport.Service.xml - gdbus-codegen \ - --interface-prefix org.tizen.messageport \ - --c-namespace MsgPort_Dbus_Glue \ - --generate-c-code dbus-service-glue \ - $< - messageportd_SOURCES = \ - dbus-manager-glue.h \ - dbus-manager-glue.c \ - dubs-service-glue.h \ - dbus-service-glue.c \ dbus-service.h \ dbus-service.c \ dbus-manager.h \ @@ -35,9 +17,12 @@ messageportd_SOURCES = \ messageportd_CPPFLAGS = \ -I$(top_builddir) \ - $(MESSAGEPORT_CFLAGS) + $(GLIB_CLFAGS) $(GIO_CFLAGS) \ + $(NULL) messageportd_LDADD = \ - $(MESSAGEPORT_LIBS) + ../common/libmessageport-dbus-glue.la \ + $(GLIB_LIBS) $(GIO_LIBS) \ + $(NULL) CLEANFILES = diff --git a/daemon/dbus-manager-doc-gen-org.tizen.messageport.Manager.xml b/daemon/dbus-manager-doc-gen-org.tizen.messageport.Manager.xml deleted file mode 100644 index 48622e1..0000000 --- a/daemon/dbus-manager-doc-gen-org.tizen.messageport.Manager.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - org.tizen.messageport.Manager - org.tizen.messageport.Manager - org.tizen.messageport.Manager - Methods - -registerService (IN s appId, - IN s port, - OUT s socketURL); -connectService (IN s remoteAppId, - IN s port); - - - - Description - - - - Method Details - - The registerService() method - org.tizen.messageport.Manager.registerService() - -registerService (IN s appId, - IN s port, - OUT s socketURL); - - - - - IN s appId: - - - - IN s port: - - - - OUT s socketURL: - - - - - - The connectService() method - org.tizen.messageport.Manager.connectService() - -connectService (IN s remoteAppId, - IN s port); - - - - - IN s remoteAppId: - - - - IN s port: - - - - - - - diff --git a/daemon/dbus-manager.c b/daemon/dbus-manager.c index a754595..73ddcf1 100644 --- a/daemon/dbus-manager.c +++ b/daemon/dbus-manager.c @@ -22,12 +22,12 @@ */ #include "dbus-manager.h" -#include "dbus-manager-glue.h" -#include "dbus-service-glue.h" +#include "common/dbus-manager-glue.h" +#include "common/dbus-service-glue.h" +#include "common/log.h" #include "dbus-service.h" #include "dbus-server.h" #include "manager.h" -#include "common/log.h" G_DEFINE_TYPE (MsgPortDbusManager, msgport_dbus_manager, G_TYPE_OBJECT) @@ -86,6 +86,8 @@ _dbus_manager_handle_register_service ( MsgPortDbusService *dbus_service = NULL; g_return_val_if_fail (dbus_mgr && MSGPORT_IS_DBUS_MANAGER (dbus_mgr), FALSE); + DBG ("register service request from %p for port %s", dbus_mgr, port_name); + dbus_service = msgport_manager_register_service ( dbus_mgr->priv->manager, dbus_mgr, port_name, is_trusted, &error); @@ -115,21 +117,24 @@ _dbus_manager_handle_check_for_remote_service ( MsgPortDbusService *dbus_service = NULL; MsgPortDbusManager *remote_dbus_manager = NULL; - g_return_val_if_fail (dbus_mgr && MSGPORT_IS_MANAGER (dbus_mgr), FALSE); + g_return_val_if_fail (dbus_mgr && MSGPORT_IS_DBUS_MANAGER (dbus_mgr), FALSE); + + DBG ("check remote service request from %p for %s %s", dbus_mgr, remote_app_id, remote_port_name); remote_dbus_manager = msgport_dbus_server_get_dbus_manager_by_app_id ( dbus_mgr->priv->server, remote_app_id); dbus_service = msgport_manager_get_service (dbus_mgr->priv->manager, - remote_dbus_manager, remote_port_name, is_trusted, &error); + remote_dbus_manager, remote_port_name, is_trusted); if (error) { g_dbus_method_invocation_take_error (invocation, error); } else { + DBG ("Found service id : %d", msgport_dbus_service_get_id (dbus_service)); msgport_dbus_glue_manager_complete_check_for_remote_service ( dbus_mgr->priv->dbus_skeleton, invocation, - msgport_dbus_service_get_object_path (dbus_service)); + msgport_dbus_service_get_id (dbus_service)); } return TRUE; @@ -139,7 +144,7 @@ static gboolean _dbus_manager_handle_send_message ( MsgPortDbusManager *dbus_mgr, GDBusMethodInvocation *invocation, - const gchar *remote_service_path, + guint service_id, GVariant *data, gpointer userdata) { @@ -148,13 +153,18 @@ _dbus_manager_handle_send_message ( g_return_val_if_fail (dbus_mgr && MSGPORT_IS_DBUS_MANAGER (dbus_mgr), FALSE); - dbus_service = msgport_manager_get_service_by_path (dbus_mgr->priv->manager, - remote_service_path, &error); + DBG ("send_message from %p : %d ", dbus_mgr, service_id); + + dbus_service = msgport_manager_get_service_by_id ( + dbus_mgr->priv->manager, service_id); if (dbus_service){ - msgport_dbus_service_send_message (dbus_service, data, NULL); + msgport_dbus_service_send_message (dbus_service, data, "", "", FALSE); + msgport_dbus_glue_manager_complete_send_message ( + dbus_mgr->priv->dbus_skeleton, invocation); } - else if(error) { + else { + /* FIXME : fill error */ g_dbus_method_invocation_take_error (invocation, error); } diff --git a/daemon/dbus-server.c b/daemon/dbus-server.c index eaa755e..f685bf0 100644 --- a/daemon/dbus-server.c +++ b/daemon/dbus-server.c @@ -38,9 +38,9 @@ G_DEFINE_TYPE (MsgPortDbusServer, msgport_dbus_server, G_TYPE_OBJECT) #define MSGPORT_DBUS_SERVER_GET_PRIV(obj) \ G_TYPE_INSTANCE_GET_PRIVATE ((obj), MSGPORT_TYPE_DBUS_SERVER, MsgPortDbusServerPrivate) -#ifndef MSGPORT_DBUS_ADDRESS -# define MSGPORT_DBUS_ADDRESS "unix:path=%s/.message_port" -#endif /* MSGPORT_DBUS_ADDRESS */ +#ifndef MESSAGEPORT_BUS_ADDRESS +# define MESSAGEPORT_BUS_ADDRESS "unix:path=%s/.message-port" +#endif /* MESSAGEPORT_BUS_ADDRESS */ enum { @@ -289,7 +289,7 @@ MsgPortDbusServer * msgport_dbus_server_new_with_address (const gchar *address) MsgPortDbusServer * msgport_dbus_server_new () { MsgPortDbusServer *server = NULL; - gchar *address = g_strdup_printf (MSGPORT_DBUS_ADDRESS, g_get_user_runtime_dir()); + gchar *address = g_strdup_printf (MESSAGEPORT_BUS_ADDRESS); //, g_get_user_runtime_dir()); server = msgport_dbus_server_new_with_address (address); g_free (address); diff --git a/daemon/dbus-service.c b/daemon/dbus-service.c index b2423cb..106d751 100644 --- a/daemon/dbus-service.c +++ b/daemon/dbus-service.c @@ -22,9 +22,9 @@ */ #include "dbus-service.h" -#include "dbus-service-glue.h" -#include "manager.h" +#include "common/dbus-service-glue.h" #include "common/log.h" +#include "manager.h" G_DEFINE_TYPE (MsgPortDbusService, msgport_dbus_service, G_TYPE_OBJECT) @@ -36,6 +36,7 @@ struct _MsgPortDbusServicePrivate { MsgPortDbusGlueService *dbus_skeleton; MsgPortService *service; gchar *object_path; + guint id; }; @@ -76,7 +77,7 @@ static gboolean _dbus_service_handle_send_message ( MsgPortDbusService *dbus_service, GDBusMethodInvocation *invocation, - const gchar *remote_service_path, + guint remote_service_id, GVariant *data, gpointer userdata) { @@ -86,14 +87,16 @@ _dbus_service_handle_send_message ( g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), FALSE); manager = msgport_dbus_manager_get_manager (dbus_service->priv->owner); - peer_dbus_service = msgport_manager_get_service_by_path (manager, remote_service_path, &error); + peer_dbus_service = msgport_manager_get_service_by_id (manager, remote_service_id); if (!peer_dbus_service) { /* FIXME: return ENOTFOUND error */ g_dbus_method_invocation_take_error (invocation, error); } else { msgport_dbus_service_send_message (peer_dbus_service, data, - dbus_service->priv->object_path); + msgport_dbus_service_get_app_id (dbus_service), + msgport_dbus_service_get_port_name (dbus_service), + msgport_dbus_service_get_is_trusted (dbus_service)); msgport_dbus_glue_service_complete_send_message ( dbus_service->priv->dbus_skeleton, invocation); } @@ -187,6 +190,7 @@ msgport_dbus_service_new (MsgPortDbusManager *owner, const gchar *name, gboolean g_free (object_path); return NULL; } + dbus_service->priv->id = object_conter; dbus_service->priv->owner = /*g_object_ref*/ (owner); dbus_service->priv->object_path = object_path; dbus_service->priv->service = msgport_service_new ( @@ -198,6 +202,14 @@ msgport_dbus_service_new (MsgPortDbusManager *owner, const gchar *name, gboolean return dbus_service; } +guint +msgport_dbus_service_get_id (MsgPortDbusService *dbus_service) +{ + g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), 0); + + return dbus_service->priv->id; +} + const gchar * msgport_dbus_service_get_object_path (MsgPortDbusService *dbus_service) { @@ -238,6 +250,14 @@ msgport_dbus_service_get_port_name (MsgPortDbusService *dbus_service) return msgport_service_get_port_name (dbus_service->priv->service); } +const gchar * +msgport_dbus_service_get_app_id (MsgPortDbusService *dbus_service) +{ + g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), NULL); + + return msgport_dbus_manager_get_app_id (dbus_service->priv->owner); +} + gboolean msgport_dbus_service_get_is_trusted (MsgPortDbusService *dbus_service) { @@ -247,11 +267,11 @@ msgport_dbus_service_get_is_trusted (MsgPortDbusService *dbus_service) } gboolean -msgport_dbus_service_send_message (MsgPortDbusService *dbus_service, GVariant *data, const gchar *from) +msgport_dbus_service_send_message (MsgPortDbusService *dbus_service, GVariant *data, const gchar *r_app_id, const gchar *r_port, gboolean r_is_trusted) { g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), FALSE); - msgport_dbus_glue_service_emit_on_message (dbus_service->priv->dbus_skeleton, data, from); + msgport_dbus_glue_service_emit_on_message (dbus_service->priv->dbus_skeleton, data, r_app_id, r_port, r_is_trusted); return TRUE; } diff --git a/daemon/dbus-service.h b/daemon/dbus-service.h index abd440e..6828893 100644 --- a/daemon/dbus-service.h +++ b/daemon/dbus-service.h @@ -69,6 +69,9 @@ msgport_dbus_service_get_connection (MsgPortDbusService *dbus_service); MsgPortService * msgport_dbus_service_get_service (MsgPortDbusService *dbus_service); +guint +msgport_dbus_service_get_id (MsgPortDbusService *dbus_service); + MsgPortDbusManager * msgport_dbus_service_get_owner (MsgPortDbusService *dbus_service); @@ -83,8 +86,10 @@ msgport_dbus_service_get_is_trusted (MsgPortDbusService *dbus_service); gboolean msgport_dbus_service_send_message (MsgPortDbusService *dbus_service, - GVariant *data, - const gchar *from); + GVariant *data, + const gchar *remote_app_id, + const gchar *remote_port_name, + gboolean remote_is_trusted); G_END_DECLS diff --git a/daemon/manager.c b/daemon/manager.c index a860819..3bf0482 100644 --- a/daemon/manager.c +++ b/daemon/manager.c @@ -33,17 +33,17 @@ G_DEFINE_TYPE (MsgPortManager, msgport_manager, G_TYPE_OBJECT) struct _MsgPortManagerPrivate { /* - * Key : const gchar * - object_path of the service + * Key : guint - Id of the service * Value : MsgPortDbusService * (transfe full) */ - GHashTable *path_service_map; /* {object_path,MsgPortDbusService} */ + GHashTable *service_cache; /* {service_id,MsgPortDbusService} */ /* * Holds services owned by a client * Key : MsgPortDbusManager * * Value : GList (tranfer none) */ - GHashTable *owner_service_map; /* {app_id,GList[MsgPortDbusService]} */ + GHashTable *owner_service_map; /* {MsgPortDbusManager*,GList[MsgPortDbusService]} */ }; static void @@ -62,8 +62,8 @@ _manager_dispose (GObject *self) g_hash_table_unref (manager->priv->owner_service_map); manager->priv->owner_service_map = NULL; - g_hash_table_unref (manager->priv->path_service_map); - manager->priv->path_service_map = NULL; + g_hash_table_unref (manager->priv->service_cache); + manager->priv->service_cache = NULL; G_OBJECT_CLASS (msgport_manager_parent_class)->dispose (self); } @@ -73,8 +73,8 @@ msgport_manager_init (MsgPortManager *self) { MsgPortManagerPrivate *priv = MSGPORT_MANAGER_GET_PRIV (self); - priv->path_service_map = g_hash_table_new_full ( - g_str_hash, g_str_equal, NULL, g_object_unref); + priv->service_cache = g_hash_table_new_full ( + g_direct_hash, g_direct_equal, NULL, g_object_unref); priv->owner_service_map = g_hash_table_new_full ( g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_list_free); @@ -116,7 +116,7 @@ msgport_manager_register_service ( gboolean is_trusted, GError **error) { - GList *service_list = NULL; /* services list by app_id */ + GList *service_list = NULL; /* services list owned by a client */ gboolean was_empty = TRUE; MsgPortDbusService *dbus_service = NULL; @@ -139,12 +139,16 @@ msgport_manager_register_service ( was_empty = (service_list == NULL); dbus_service = msgport_dbus_service_new (owner, port_name, is_trusted); + if (!dbus_service) { + /* FIXME : return NOMEMERY error */ + return NULL; + } /* cache newly created service */ - g_hash_table_insert (manager->priv->path_service_map, - (gpointer)msgport_dbus_service_get_object_path (dbus_service), + g_hash_table_insert (manager->priv->service_cache, + GINT_TO_POINTER (msgport_dbus_service_get_id (dbus_service)), (gpointer)dbus_service); - /* append to list of services */ + /* append to list of services */ service_list = g_list_append (service_list, dbus_service); if (was_empty) { g_hash_table_insert (manager->priv->owner_service_map, owner, service_list); @@ -158,8 +162,7 @@ msgport_manager_get_service ( MsgPortManager *manager, MsgPortDbusManager *owner, const gchar *remote_port_name, - gboolean is_trusted, - GError **error) + gboolean is_trusted) { GList *service_list = NULL; g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), NULL); @@ -181,19 +184,15 @@ msgport_manager_get_service ( } MsgPortDbusService * -msgport_manager_get_service_by_path ( +msgport_manager_get_service_by_id ( MsgPortManager *manager, - const gchar *service_object_path, - GError **error) + guint service_id) { MsgPortDbusService *dbus_service = NULL; g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), NULL); - dbus_service = g_hash_table_lookup (manager->priv->path_service_map, service_object_path); - - if (!dbus_service) { - /* FIXME: return ENOTFOUND error */ - } + dbus_service = MSGPORT_DBUS_SERVICE (g_hash_table_lookup ( + manager->priv->service_cache, GINT_TO_POINTER(service_id))); return dbus_service; } @@ -203,19 +202,14 @@ _unref_dbus_manager_cb (gpointer data, gpointer user_data) { MsgPortDbusService *service = MSGPORT_DBUS_SERVICE (data); MsgPortManager *manager = MSGPORT_MANAGER (user_data); - const gchar *object_path = NULL; - - g_assert (manager); - g_assert (service); - object_path = msgport_dbus_service_get_object_path (service); + guint id = msgport_dbus_service_get_id (service); - DBG ("Unregistering service %s:%s(%s)", + DBG ("Unregistering service %s:%s(%d)", msgport_dbus_manager_get_app_id (msgport_dbus_service_get_owner (service)), - msgport_dbus_service_get_port_name (service), - object_path); - /* remove the service from object_path:service map, + msgport_dbus_service_get_port_name (service), id); + /* remove the service from id:service map, * as its being unregisted */ - g_hash_table_remove (manager->priv->path_service_map, object_path); + g_hash_table_remove (manager->priv->service_cache, GINT_TO_POINTER(id)); } /* @@ -245,19 +239,19 @@ DBG("}"); } /* - * unregister a signle service for given object path + * unregister a signle service for given service id */ gboolean msgport_manager_unregister_service ( MsgPortManager *manager, - const gchar *service_object_path) + gint service_id) { MsgPortDbusService *service = NULL; MsgPortDbusManager *owner = NULL; GList *service_list = NULL, *new_service_list = NULL; g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), FALSE); -DBG ("{"); - service = g_hash_table_lookup (manager->priv->path_service_map, service_object_path); + + service = g_hash_table_lookup (manager->priv->service_cache, GINT_TO_POINTER (service_id)); if (!service) return FALSE; @@ -273,9 +267,9 @@ DBG ("{"); g_hash_table_insert (manager->priv->owner_service_map, owner, new_service_list); } - /* remove from the object_path:servcie table */ - g_hash_table_remove (manager->priv->path_service_map, service_object_path); -DBG("}"); + /* remove from the service_id:servcie table */ + g_hash_table_remove (manager->priv->service_cache, GINT_TO_POINTER(service_id)); + return TRUE; } diff --git a/daemon/manager.h b/daemon/manager.h index 28c6610..722b489 100644 --- a/daemon/manager.h +++ b/daemon/manager.h @@ -73,14 +73,17 @@ msgport_manager_get_service ( MsgPortManager *manager, MsgPortDbusManager *owner, const gchar *remote_port_name, - gboolean is_trusted, - GError **error_out); + gboolean is_trusted); MsgPortDbusService * -msgport_manager_get_service_by_path ( +msgport_manager_get_service_by_id ( MsgPortManager *manager, - const gchar *object_path, - GError **error_out); + guint service_id); + +gboolean +msgport_manager_unregister_services ( + MsgPortManager *manager, + MsgPortDbusManager *owned_by); G_END_DECLS diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..4ccd858 --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,8 @@ +bin_PROGRAMS = msgport-example-app + +msgport_example_app_SOURCES = test-app.c + +msgport_example_app_LDADD = ../lib/libmessage-port.la $(GLIB_LIBS) $(BUNDLE_LIBS) + +msgport_example_app_CPPFLAGS = -I../lib/ $(GLIB_CFLAGS) $(BUNDLE_CFLAGS) + diff --git a/examples/test-app.c b/examples/test-app.c new file mode 100644 index 0000000..4abf38b --- /dev/null +++ b/examples/test-app.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include + +GMainLoop *__loop = NULL; + +static void _dump_data (const char *key, const int type, const bundle_keyval_t *kv, void *user_data) +{ + gchar *val = NULL; + size_t size; + bundle_keyval_get_basic_val ((bundle_keyval_t*)kv, (void**)&val, &size); + g_print (" %s - %s\n", key, val); +} + +void (_on_got_message)(int port_id, const char* remote_app_id, const char* remote_port, gboolean trusted_message, bundle* data) +{ + gchar *name = NULL; + messageport_get_local_port_name (port_id, &name), + g_print ("SERVER: GOT MESSAGE at prot %s FROM :'%s' - '%s\n", name, + remote_app_id ? remote_app_id : "unknwon app", remote_port ? remote_port : "unknwon"); + g_free (name); + + g_assert (data); + + bundle_foreach (data, _dump_data, NULL); + + g_main_loop_quit (__loop); +} + +int main (int argc, char *argv[]) +{ + const gchar *port_name = "test_port"; + pid_t child_pid; + + __loop = g_main_loop_new (NULL, FALSE); + child_pid = fork (); + + if (child_pid < 0) { + g_error ("Failed to fork "); + } + else if (child_pid > 0) { + /* prent process : server port */ + int port_id = messageport_register_local_port (port_name, _on_got_message); + + if (port_id > MESSAGEPORT_ERROR_NONE) { + gchar *name = NULL; + messageport_get_local_port_name (port_id, &name); + g_print ("Registerd Port : %s(Id: %d)\n", name, port_id); + g_free (name); + } + else { + g_print ("Failed to register port : %d \n", port_id); + return -1; + } + } + else { + /* child process */ + /* sleep sometime till server port is ready */ + sleep (5); + gchar *app_id = g_strdup_printf ("%d", getppid()); + gboolean found; + messageport_error_e res = messageport_check_remote_port (app_id, port_name, &found); + + if (!found) { + g_print ("CHILD : Could not found remote port (%d)", res); + return -1; + } + + g_print ("CHILD : Found remote prot\n"); + + bundle *b = bundle_create (); + + bundle_add (b, "Name", "Amarnath"); + bundle_add (b, "Email", "amarnath.valluri@intel.com"); + + g_print ("CHILD : Sending data ....\n"); + res = messageport_send_message (app_id, port_name, b); + bundle_free (b); + if (res != MESSAGEPORT_ERROR_NONE) + { + g_print ("CHILD: Faile to send message to server : %d", res); + } + else g_print ("CHILD : Data sent successfully"); + + exit (0); + } + + g_main_loop_run (__loop); + + g_main_loop_unref (__loop); + + return 0; +} + diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..85fa812 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,30 @@ +NULL = +lib_LTLIBRARIES = libmessage-port.la +libmessage_port_la_SOURCES = \ + message-port.c \ + msgport-utils.h \ + msgport-utils.c \ + msgport-service.h \ + msgport-service.c \ + msgport-manager.h \ + msgport-manager.c \ + $(NULL) + +libmessage_port_la_includedir = $(includedir)/ +libmessage_port_la_include_HEADERS = \ + message-port.h \ + $(NULL) + +libmessage_port_la_CPPFLAGS = \ + -I . \ + -I $(top_builddir) \ + -I $(top_builddir)/daemon \ + $(GLIB_CFLAGS) $(GIO_CFLAGS) $(BUNDLE_CFLAGS) \ + -Wall -error + $(NULL) + +libmessage_port_la_LIBADD = \ + ../common/libmessageport-dbus-glue.la \ + $(GLIB_LIBS) $(GIO_LIBS) $(BUNDLE_LIBS) + + diff --git a/lib/message-port.c b/lib/message-port.c index c2903ce..249dc11 100644 --- a/lib/message-port.c +++ b/lib/message-port.c @@ -1,47 +1,45 @@ #include "message-port.h" +#include "msgport-manager.h" +#include "msgport-utils.h" +#include "common/log.h" static int _messageport_register_port (const char *name, gboolean is_trusted, messageport_message_cb cb) { - (void) name; - (void) is_trusted; - (void) cb; + int port_id = 0; /* id of the port created */ + messageport_error_e res; + MsgPortManager *manager = msgport_get_manager (); - return MESSAGEPORT_ERROR_NONE; + res = msgport_manager_register_service (manager, name, is_trusted, cb, &port_id); + + return port_id > 0 ? port_id : (int)res; } static int _messageport_check_remote_port (const char *app_id, const char *port, gboolean is_trusted, gboolean *exists) { - (void) app_id; - (void) port; - (void) is_trusted; + guint service_id; + messageport_error_e res; + MsgPortManager *manager = msgport_get_manager (); - if (exists) *exists = FALSE; + res = msgport_manager_check_remote_service (manager, app_id, port, FALSE, &service_id); - return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; -} + if (exists) *exists = (res == MESSAGEPORT_ERROR_NONE); -static int -_messageport_send_message (const char *app_id, const char *port, gboolean is_trusted, bundle *message) -{ - (void) app_id; - (void) port; - (void) is_trusted; - (void) message; - - return MESSAGEPORT_ERROR_NONE; + return (int) res; } static int -_messageport_get_port_name (int port_id, gboolean is_trusted, gchar **name_out) +_messageport_send_message (const char *app_id, const char *port, gboolean is_trusted, bundle *message) { - (void) port_id; - (void) is_trusted; - - if (name_out) **name_out = ""; - - return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; +DBG("{"); + MsgPortManager *manager = msgport_get_manager (); + GVariant *v_data = bundle_to_variant_map (message); + messageport_error_e res; + + res = msgport_manager_send_message (manager, app_id, port, is_trusted, v_data); +DBG("}"); + return (int) res; } /* @@ -88,13 +86,19 @@ int messageport_send_bidirectional_trusted_message (int id, const char *remote_a return _messageport_send_message (remote_app_id, remote_port, TRUE, data); } -int messageport_get_local_port_name(int id, char **name) +int messageport_get_local_port_name(int port_id, char **name_out) { - return _messageport_get_port_name (id, FALSE, name); + MsgPortManager *manager = msgport_get_manager (); + + return (int)msgport_manager_get_service_name (manager, port_id, name_out); } -int messageport_check_trusted_local_port (int id, char **name) +int messageport_check_trusted_local_port (int id, bool *exists) { - return _messageport_get_port_name (id, TRUE, name); + (void) id; + + if (exists) *exists = FALSE; + + return MESSAGEPORT_ERROR_NONE; } diff --git a/lib/message-port.h b/lib/message-port.h index 8d7bacc..31a94b8 100644 --- a/lib/message-port.h +++ b/lib/message-port.h @@ -10,13 +10,16 @@ #endif #include +#include + +typedef gboolean bool; G_BEGIN_DECLS /** * @brief Enumerations of error code for Application. */ -typedef enum +typedef enum _messageport_error_e { MESSAGEPORT_ERROR_NONE = 0, /**< Successful */ MESSAGEPORT_ERROR_IO_ERROR = -1, /**< Internal I/O error */ @@ -226,7 +229,6 @@ EXPORT_API int messageport_get_local_port_name(int id, char **name); */ EXPORT_API int messageport_check_trusted_local_port(int id, bool *trusted); - -G_EDN_DECLS +G_END_DECLS #endif /* __MESSAGE_PORT_H */ diff --git a/lib/msgport-manager.c b/lib/msgport-manager.c index c4783a1..ca762c9 100644 --- a/lib/msgport-manager.c +++ b/lib/msgport-manager.c @@ -1,73 +1,164 @@ #include "msgport-manager.h" -#include "message-port.h" +#include "msgport-service.h" +#include "message-port.h" /* MESSAGEPORT_ERROR */ +#include "common/dbus-manager-glue.h" #include "common/log.h" -#include "dbus-manager-glue.h" +#include "config.h" /* MESSAGEPORT_BUS_ADDRESS */ #include struct _MsgPortManager { - MsgPortGlueManagerPorxy *proxy; + GObject parent; + + MsgPortDbusGlueManager *proxy; GHashTable *services; /* {gchar*:MsgPortService*} */ - GList *local_service_list; - int n_local_services; + GHashTable *local_services; /* {gint: gchar *} */ + GHashTable *remote_services; /* {gint: gchar *} */ }; -static MsgPortManager __manager; +G_DEFINE_TYPE (MsgPortManager, msgport_manager, G_TYPE_OBJECT) -MsgPortManager * msgport_manager_new () +static void +_unregister_service_cb (int service_id, const gchar *object_path, MsgPortManager *manager) +{ + MsgPortService *service = g_hash_table_lookup (manager->services, object_path); + + if (service) msgport_service_unregister (service); +} + +static void +_finalize (GObject *self) +{ + MsgPortManager *manager = MSGPORT_MANAGER (self); + + if (manager->local_services) { + g_hash_table_unref (manager->local_services); + manager->local_services = NULL; + } + + if (manager->remote_services) { + g_hash_table_unref (manager->remote_services); + manager->remote_services = NULL; + } + + G_OBJECT_CLASS (msgport_manager_parent_class)->finalize (self); +} + +static void +_dispose (GObject *self) +{ + MsgPortManager *manager = MSGPORT_MANAGER (self); + + g_hash_table_foreach (manager->local_services, (GHFunc)_unregister_service_cb, manager); + + if (manager->services) { + g_hash_table_unref (manager->services); + manager->services = NULL; + } + + g_clear_object (&manager->proxy); + + G_OBJECT_CLASS (msgport_manager_parent_class)->dispose (self); +} + +static void +msgport_manager_class_init (MsgPortManagerClass *klass) +{ + GObjectClass *g_klass = G_OBJECT_CLASS (klass); + + g_klass->finalize = _finalize; + g_klass->dispose = _dispose; +} + +static void +msgport_manager_init (MsgPortManager *manager) { GError *error = NULL; GDBusConnection *connection = NULL; - MsgPortManager *manager = g_slice_new0(MsgPortManager); - gchar *bus_address = g_strdup_printf (MESSAGEPORT_BUS_ADDRESS, g_get_user_runtime_dir()); + gchar *bus_address = g_strdup_printf (MESSAGEPORT_BUS_ADDRESS); - if (!manager) { - return NULL; - } + manager->services = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + manager->local_services = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); + manager->remote_services = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); connection = g_dbus_connection_new_for_address_sync (bus_address, - G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, - NULL, NULL, &error); - + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, &error); if (error) { - ERR ("Unable to get bus connection for address %s: %s", bus_address, error->message); + WARN ("Fail to connect messageport server at address %s: %s", bus_address, error->message); g_error_free (error); - goto fail; } - - manager->services = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify)g_object_unref); - manager->local_servcie_list = NULL; - manager->n_local_services = 0; - manager->proxy = msgport_dbus_glue_manager_proxy_new_sync ( + else { + manager->proxy = msgport_dbus_glue_manager_proxy_new_sync ( connection, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, "/", NULL, &error); + if (error) { + WARN ("Fail to get manager proxy : %s", error->message); + g_error_free (error); + } + } +} - if (!manager->proxy) { - ERR ("Unable to get manager proxy : %s", error->message); - g_error_free (error); - goto fail; +MsgPortManager * msgport_manager_new () +{ + return g_object_new (MSGPORT_TYPE_MANAGER, NULL); +} + +static MsgPortManager *__manager; + +MsgPortManager * msgport_get_manager () +{ + if (!__manager) { + __manager = msgport_manager_new (); } - return manager; + return __manager; +} -fail: - if (manager) msgport_manager_unref (manager); - return NULL; +static int +_create_and_cache_service (MsgPortManager *manager, gchar *object_path, messageport_message_cb cb) +{ + int id; + MsgPortService *service = msgport_service_new ( + g_dbus_proxy_get_connection (G_DBUS_PROXY(manager->proxy)), + object_path, cb); + if (!service) { + return MESSAGEPORT_ERROR_IO_ERROR; + } + + id = msgport_service_id (service); + + g_hash_table_insert (manager->services, object_path, service); + g_hash_table_insert (manager->local_services, GINT_TO_POINTER (id), object_path); + + return id; } -MsgPortManager * msgport_get_manager () { - if (!__manager) - __manager = magport_manager_new (); +static MsgPortService * +_get_local_port (MsgPortManager *manager, int service_id) +{ + const gchar *object_path = NULL; + MsgPortService *service = NULL; + + object_path = g_hash_table_lookup (manager->local_services, GINT_TO_POINTER(service_id)); + if (!object_path) return NULL; - return __manager; + service = MSGPORT_SERVICE (g_hash_table_lookup (manager->services, object_path)); + if (!service) { + g_hash_table_remove (manager->local_services, GINT_TO_POINTER (service_id)); + return NULL; + } + + return service; } -int msgport_manager_register_service (MsgPortManager *manger, const gchar *port_name, gboolean is_trusted) +messageport_error_e +msgport_manager_register_service (MsgPortManager *manager, const gchar *port_name, gboolean is_trusted, messageport_message_cb message_cb, int *service_id) { GError *error = NULL; - g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR); + gchar *object_path = NULL; - if (!port_name) return MESSAGEPORT_ERROR_INVALID_PARAMETER; + g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR); + g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR); + g_return_val_if_fail (service_id && port_name && message_cb, MESSAGEPORT_ERROR_INVALID_PARAMETER); msgport_dbus_glue_manager_call_register_service_sync (manager->proxy, port_name, is_trusted, &object_path, NULL, &error); @@ -78,41 +169,105 @@ int msgport_manager_register_service (MsgPortManager *manger, const gchar *port_ return MESSAGEPORT_ERROR_IO_ERROR; } - MsgPortService *service = msgport_service_new ( - g_dbus_proxy_get_connection (G_DBUS_PROXY(manager->proxy)), - object_path, &error); + *service_id = _create_and_cache_service (manager, object_path, message_cb); + + return MESSAGEPORT_ERROR_NONE; +} + +messageport_error_e +msgport_manager_unregister_servcie (MsgPortManager *manager, int service_id) +{ + const gchar *object_path = NULL; + MsgPortService *service = NULL; + g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), FALSE); + g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR); + + service = _get_local_port (manager, service_id); if (!service) { - WARN ("unable to get service proxy for path %s: %s", object_path, error->message); - g_error_free (error); - g_free (object_path); - return MESSAGEPORT_ERROR_IO_ERROR; + return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; } - g_hash_table_insert (manager->services, object_path, service); - manager->local_service_list = g_list_append (manager->local_service_list, object_path); - manager->n_local_services++; + if (!msgport_service_unregister (service)) + return MESSAGEPORT_ERROR_IO_ERROR; - return manager->n_local_services; + object_path = (const gchar *)g_hash_table_lookup (manager->local_services, + GINT_TO_POINTER(service_id)); + g_hash_table_remove (manager->local_services, GINT_TO_POINTER(service_id)); + g_hash_table_remove (manager->services, object_path); + + return MESSAGEPORT_ERROR_NONE; } -MsgPortService * -msgport_service_new (GDBusConnection *connection, const gchar *path, GError **error) +messageport_error_e +msgport_manager_check_remote_service (MsgPortManager *manager, const gchar *app_id, const gchar *port, gboolean is_trusted, guint *service_id_out) { - MsgPortService *service = g_object_new (MSGPORT_TYPE_SERVICE, NULL); + GError *error = NULL; + guint remote_service_id = 0; - if (!service) { - /* FIXME: return no merory error */ - return NULL + if (service_id_out) *service_id_out = 0; + + g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR); + g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR); + g_return_val_if_fail (app_id && port, MESSAGEPORT_ERROR_INVALID_PARAMETER); + + if (!app_id || !port) return MESSAGEPORT_ERROR_INVALID_PARAMETER; + + msgport_dbus_glue_manager_call_check_for_remote_service_sync (manager->proxy, + app_id, port, is_trusted, &remote_service_id, NULL, &error); + + if (error) { + WARN ("No service found for app_id %s, port name %s: %s", app_id, port, error->message); + g_error_free (error); + return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; } + else { + DBG ("Got service id %d for %s, %s", remote_service_id, app_id, port); - service->proxy = msgport_dbus_glue_service_proxy_new_sync (connection, - g_dbus_proxy_get_connection (G_DBUS_PROXY(manager->proxy)), - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, object_path, NULL, error); - if (!service->proxy) { - g_object_unref (service); - return NULL; + if (service_id_out) *service_id_out = remote_service_id; } - return service; + return MESSAGEPORT_ERROR_NONE; +} + +messageport_error_e +msgport_manager_get_service_name (MsgPortManager *manager, int service_id, gchar **name_out) +{ + MsgPortService *service = NULL; + g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR); + g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR); + g_return_val_if_fail (name_out && service_id, MESSAGEPORT_ERROR_INVALID_PARAMETER); + + service = _get_local_port (manager, service_id); + if (!service) return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; + + *name_out = g_strdup (msgport_service_name (service)); + DBG ("PORT NAME : %s", *name_out); + + return MESSAGEPORT_ERROR_NONE; +} + +messageport_error_e +msgport_manager_send_message (MsgPortManager *manager, const gchar *remote_app_id, const gchar *remote_port, gboolean is_trusted, GVariant *data) +{ + guint service_id = 0; + messageport_error_e res = MESSAGEPORT_ERROR_NONE; + GError *error = NULL; + + g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR); + g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR); + g_return_val_if_fail (remote_app_id && remote_port, MESSAGEPORT_ERROR_INVALID_PARAMETER); + + res = msgport_manager_check_remote_service (manager, remote_app_id, remote_port, is_trusted, &service_id); + if (service_id == 0) return res; + + msgport_dbus_glue_manager_call_send_message_sync (manager->proxy, service_id, data, NULL, &error); + + if (error) { + WARN ("Failed to send message to (%s:%s) : %s", remote_app_id, remote_port, error->message); + g_error_free (error); + res = MESSAGEPORT_ERROR_IO_ERROR; + } + + return res; } diff --git a/lib/msgport-manager.h b/lib/msgport-manager.h index 9125797..5718fd0 100644 --- a/lib/msgport-manager.h +++ b/lib/msgport-manager.h @@ -1,21 +1,50 @@ #ifndef __MSGPORT_MANAGER_H #define __MSGPORT_MANAGER_H -typedef _MsgPortManager MsgPortManager; -typedef _MsgPortService MsgPortService; +#include +#include +#include + +#define MSGPORT_TYPE_MANAGER (msgport_manager_get_type()) +#define MSGPORT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MSGPORT_TYPE_MANAGER, MsgPortManager)) +#define MSGPORT_MANAGER_CLASS(kls) (G_TYPE_CHECK_CLASS_CAST((kls), MSGPORT_TYPE_MANAGER, MsgPortManagerClass)) +#define MSGPORT_IS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MSGPORT_TYPE_MANAGER)) +#define MSGPORT_IS_MANAGER_CLASS(kls) (G_TYPE_CHECK_CLASS_TYPE((kls), MSGPORT_TYPE_MANAGER) + +typedef struct _MsgPortManager MsgPortManager; +typedef struct _MsgPortManagerClass MsgPortManagerClass; +typedef struct _MsgPortService MsgPortService; + +G_BEGIN_DECLS + +struct _MsgPortManagerClass +{ + GObjectClass parent_class; +}; + +GType msgport_manager_get_type (void); MsgPortManager * msgport_get_manager (); -int -msgport_manager_register_port (MsgPortManager *manager, const gchar *port_name, gboolean is_trusted); +messageport_error_e +msgport_manager_register_service (MsgPortManager *manager, const gchar *port_name, gboolean is_trusted, messageport_message_cb cb, int *service_id_out); + +messageport_error_e +msgport_manager_check_remote_service (MsgPortManager *manager, const gchar *remote_app_id, const gchar *port_name, gboolean is_trusted, guint *service_id_out); + +messageport_error_e +msgport_manager_get_service_name (MsgPortManager *manager, int port_id, gchar **name_out); -int -msgport_manager_unregister_port (MsgPortManager *manager, int port_id); +messageport_error_e +msgport_manager_unregister_service (MsgPortManager *manager, int service_id); -int -msgport_manager_get_port_id (MsgPortManager *manager, const gchar *remote_app_id, const gchar *port_name, gboolean is_trusted); +messageport_error_e +msgport_manager_send_message (MsgPortManager *manager, const gchar *remote_app_id, const gchar *port_name, gboolean is_trusted, GVariant *data); +messageport_error_e +msgport_manager_send_bidirectional_message (MsgPortManager *manager, int from_id, const gchar *remote_app_id, const gchar *port_name, gboolean is_trusted, GVariant *data); +G_END_DECLS -#define /* __MSGPORT_MANAGER_PROXY_H */ +#endif /* __MSGPORT_MANAGER_PROXY_H */ diff --git a/lib/msgport-service.c b/lib/msgport-service.c new file mode 100644 index 0000000..8ccb448 --- /dev/null +++ b/lib/msgport-service.c @@ -0,0 +1,165 @@ +#include "msgport-service.h" +#include "msgport-utils.h" +#include "common/dbus-service-glue.h" +#include "common/log.h" +#include + + +struct _MsgPortService +{ + GObject parent; + + MsgPortDbusGlueService *proxy; + + int id; /* unique service id */ + gchar *name; /* service name */ + gboolean is_trusted; /* is trusted service */ + + guint on_messge_signal_id; + messageport_message_cb client_cb; +}; + +static int __object_counter; + +G_DEFINE_TYPE(MsgPortService, msgport_service, G_TYPE_OBJECT) + +static void +_service_finalize (GObject *self) +{ + MsgPortService *service = MSGPORT_SERVICE (self); + + g_free (service->name); + + G_OBJECT_CLASS (msgport_service_parent_class)->finalize (self); +} + +static void +_service_dispose (GObject *self) +{ + MsgPortService *service = MSGPORT_SERVICE (self); + + g_clear_object (&service->proxy); + + G_OBJECT_CLASS(msgport_service_parent_class)->dispose (self); +} + +static void +msgport_service_class_init (MsgPortServiceClass *klass) +{ + GObjectClass *g_klass = G_OBJECT_CLASS(klass); + + g_klass->dispose = _service_dispose; + g_klass->finalize = _service_finalize; +} + +static void +msgport_service_init (MsgPortService *service) +{ + service->proxy = NULL; + service->id = 0; + service->name = NULL; + service->is_trusted = FALSE; + service->client_cb = NULL; + service->on_messge_signal_id = 0; +} + +static void +_on_got_message (MsgPortService *service, GVariant *data, const gchar *remote_app_id, const gchar *remote_port, gboolean remote_is_trusted, gpointer userdata) +{ + gchar *str_data = g_variant_print (data, TRUE); + DBG ("Message received : %s(%d)", str_data, g_variant_n_children (data)); + g_free (str_data); + bundle *b = bundle_from_variant_map (data); + + service->client_cb (service->id, remote_app_id, remote_port, remote_is_trusted, b); + + bundle_free (b); +} + +MsgPortService * +msgport_service_new (GDBusConnection *connection, const gchar *path, messageport_message_cb message_cb) +{ + GVariant *properties = NULL; + GVariantIter iter; + GError *error = NULL; + MsgPortService *service = g_object_new (MSGPORT_TYPE_SERVICE, NULL); + + if (!service) { + /* FIXME: return no merory error */ + return NULL; + } + + service->proxy = msgport_dbus_glue_service_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, path, NULL, &error); + if (!service->proxy) { + g_object_unref (service); + WARN ("failed create servie proxy for path '%s' : %s", path, + error->message); + g_error_free (error); + return NULL; + } + + service->id = ++__object_counter; + + if (msgport_dbus_glue_service_call_get_properties_sync (service->proxy, &properties, NULL, &error)) { + gchar *key = NULL; + GVariant *value = NULL; + g_variant_iter_init (&iter, properties); + + while (g_variant_iter_next (&iter, "{sv}", &key, &value)) { + if ( !g_strcmp0 (key, "PortName")) service->name = g_strdup (g_variant_get_string (value, NULL)); + else if ( !g_strcmp0 (key, "IsTrusted")) service->is_trusted = g_variant_get_boolean (value); + else { + WARN ("Unknown property : %s", key); + } + + g_free (key); + g_variant_unref (value); + } + } + else { + WARN ("Failed to get properties from service proxy '%s' : %s", + path, error->message); + g_error_free (error); + } + + service->client_cb = message_cb; + service->on_messge_signal_id = g_signal_connect_swapped (service->proxy, "on-message", G_CALLBACK (_on_got_message), service); + + return service; +} + + +const gchar * +msgport_service_name (MsgPortService *service) +{ + g_return_val_if_fail (service && MSGPORT_IS_SERVICE (service), NULL); + + return service->name; +} + +gboolean +msgport_service_is_trusted (MsgPortService *service) +{ + g_return_val_if_fail (service && MSGPORT_IS_SERVICE (service), FALSE); + + return service->is_trusted; +} + +int +msgport_service_id (MsgPortService *service) +{ + g_return_val_if_fail (service && MSGPORT_IS_SERVICE (service), 0); + + return service->id; +} + +gboolean +msgport_service_unregister (MsgPortService *service) +{ + g_return_val_if_fail (service && MSGPORT_IS_SERVICE (service), FALSE); + + return TRUE; +} + diff --git a/lib/msgport-service.h b/lib/msgport-service.h new file mode 100644 index 0000000..9fb5d74 --- /dev/null +++ b/lib/msgport-service.h @@ -0,0 +1,44 @@ +#ifndef __MSGPORT_SERVICE_H +#define __MSGPORT_SERVICE_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define MSGPORT_TYPE_SERVICE (msgport_service_get_type()) +#define MSGPORT_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MSGPORT_TYPE_SERVICE, MsgPortService)) +#define MSGPORT_IS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MSGPORT_TYPE_SERVICE)) +#define MSGPORT_SERVICE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), MSGPORT_TYPE_SERVICE, MsgPortServiceClass)) +#define MSGPORT_IS_SERVICE_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), MSGPORT_TYPE_SERVICE)) + +typedef struct _MsgPortService MsgPortService; +typedef struct _MsgPortServiceClass MsgPortServiceClass; + +struct _MsgPortServiceClass +{ + GObjectClass parent_class; +}; + +GType msgport_service_get_type(void); + +MsgPortService * +msgport_service_new (GDBusConnection *connection, const gchar *path, messageport_message_cb message_cb); + +const gchar * +msgport_service_name (MsgPortService *service); + +gboolean +msgport_service_is_trusted (MsgPortService *service); + +int +msgport_service_id (MsgPortService *service); + +gboolean +msgport_service_unregister (MsgPortService *service); + +G_END_DECLS + +#endif /* __MSGPORT_SERVICE_H */ diff --git a/lib/msgport-utils.c b/lib/msgport-utils.c new file mode 100644 index 0000000..758dcb1 --- /dev/null +++ b/lib/msgport-utils.c @@ -0,0 +1,53 @@ +#include "msgport-utils.h" +#include "common/log.h" + +static void +_bundle_iter_cb (const char *key, const int type, const bundle_keyval_t *kv, void *user_data) +{ + GVariantBuilder *builder = (GVariantBuilder *)user_data; + void *val; + size_t size; + + /* NOTE: we support only string values as + * MessagePort API support key,value strings + */ + if (bundle_keyval_get_type ((bundle_keyval_t*)kv) != BUNDLE_TYPE_STR) return; + + bundle_keyval_get_basic_val ((bundle_keyval_t*)kv, &val, &size); + + g_variant_builder_add (builder, "{sv}", key, g_variant_new_string ((const gchar *)val)); +} + +GVariant * bundle_to_variant_map (bundle *b) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + + bundle_foreach (b, _bundle_iter_cb, &builder); + + return g_variant_builder_end (&builder); +} + +bundle * bundle_from_variant_map (GVariant *v_data) +{ + bundle *b = NULL; + GVariantIter iter; + gchar *key = NULL; + GVariant *value = NULL; + + if (!v_data) return b; + + g_variant_iter_init (&iter, v_data); + + b = bundle_create (); + + while (g_variant_iter_next (&iter, "{sv}", &key, &value)) { + bundle_add (b, key, g_variant_get_string (value, NULL)); + g_free (key); + g_variant_unref (value); + } + + return b; +} + diff --git a/lib/msgport-utils.h b/lib/msgport-utils.h new file mode 100644 index 0000000..b1f681e --- /dev/null +++ b/lib/msgport-utils.h @@ -0,0 +1,10 @@ +#ifndef __MSGPORT_UTILS_H +#define __MSGPORT_UTILS_ + +#include +#include + +GVariant *bundle_to_variant_map (bundle *b); +bundle *bundle_from_variant_map (GVariant *v); + +#endif /* __MSGPORT_UTILS_H */ -- 2.7.4