1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of message-port.
6 * Copyright (C) 2013 Intel Corporation.
8 * Contact: Amarnath Valluri <amarnath.valluri@linux.intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 #include "config.h" /* MESSAGEPORT_BUS_ADDRESS */
27 #include "msgport-manager.h"
28 #include "msgport-service.h"
29 #include "msgport-utils.h" /* msgport_daemon_error_to_error */
30 #include "message-port.h" /* messageport_error_e */
31 #include "common/dbus-manager-glue.h"
32 #ifdef USE_SESSION_BUS
33 #include "common/dbus-server-glue.h"
35 #include "common/log.h"
38 struct _MsgPortManager
42 MsgPortDbusGlueManager *proxy;
43 GHashTable *services; /* {gchar*:MsgPortService*} */
44 GHashTable *local_services; /* {gint: gchar *} */
45 GHashTable *remote_services; /* {gint: gchar *} */
48 G_DEFINE_TYPE (MsgPortManager, msgport_manager, G_TYPE_OBJECT)
51 _unregister_service_cb (int service_id, const gchar *object_path, MsgPortManager *manager)
53 MsgPortService *service = g_hash_table_lookup (manager->services, object_path);
55 if (service) msgport_service_unregister (service);
59 _finalize (GObject *self)
61 MsgPortManager *manager = MSGPORT_MANAGER (self);
63 if (manager->local_services) {
64 g_hash_table_unref (manager->local_services);
65 manager->local_services = NULL;
68 if (manager->remote_services) {
69 g_hash_table_unref (manager->remote_services);
70 manager->remote_services = NULL;
73 G_OBJECT_CLASS (msgport_manager_parent_class)->finalize (self);
77 _dispose (GObject *self)
79 MsgPortManager *manager = MSGPORT_MANAGER (self);
81 g_hash_table_foreach (manager->local_services, (GHFunc)_unregister_service_cb, manager);
83 if (manager->services) {
84 g_hash_table_unref (manager->services);
85 manager->services = NULL;
88 g_clear_object (&manager->proxy);
90 G_OBJECT_CLASS (msgport_manager_parent_class)->dispose (self);
94 msgport_manager_class_init (MsgPortManagerClass *klass)
96 GObjectClass *g_klass = G_OBJECT_CLASS (klass);
98 g_klass->finalize = _finalize;
99 g_klass->dispose = _dispose;
103 msgport_manager_init (MsgPortManager *manager)
105 GError *error = NULL;
106 GDBusConnection *connection = NULL;
107 gchar *bus_address = NULL;
109 manager->services = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
110 manager->local_services = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
111 manager->remote_services = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
113 #ifdef USE_SESSION_BUS
114 MsgPortDbusGlueServer *server = NULL;
115 server = msgport_dbus_glue_server_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
116 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
117 "org.tizen.messageport", "/", NULL, &error);
120 WARN ("fail to get server proxy : %s", error->message);
121 g_error_free (error);
124 msgport_dbus_glue_server_call_get_bus_address_sync (server, &bus_address, NULL, &error);
126 WARN ("Fail to get server bus address : %s", error->message);
127 g_error_free (error);
131 g_object_unref (server);
134 if (g_getenv("MESSAGEPORT_BUS_ADDRESS")) {
135 bus_address = g_strdup (g_getenv ("MESSAGEPORT_BUS_ADDRESS"));
138 # ifdef MESSAGEPORT_BUS_ADDRESS
139 bus_address = g_strdup_printf (MESSAGEPORT_BUS_ADDRESS);
144 bus_address = g_strdup_printf ("unix:path=%s/.message-port", g_get_user_runtime_dir());
146 connection = g_dbus_connection_new_for_address_sync (bus_address,
147 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, &error);
149 WARN ("Fail to connect messageport server at address %s: %s", bus_address, error->message);
150 g_error_free (error);
153 manager->proxy = msgport_dbus_glue_manager_proxy_new_sync (
154 connection, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, "/", NULL, &error);
156 WARN ("Fail to get manager proxy : %s", error->message);
157 g_error_free (error);
161 g_free (bus_address);
164 MsgPortManager * msgport_manager_new ()
166 return g_object_new (MSGPORT_TYPE_MANAGER, NULL);
169 static messageport_error_e
170 _create_and_cache_service (MsgPortManager *manager, gchar *object_path, messageport_message_cb cb, int *service_id)
173 MsgPortService *service = msgport_service_new (
174 g_dbus_proxy_get_connection (G_DBUS_PROXY(manager->proxy)),
177 g_free (object_path);
178 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
181 id = msgport_service_id (service);
183 g_hash_table_insert (manager->services, object_path, service);
184 g_hash_table_insert (manager->local_services, GINT_TO_POINTER (id), object_path);
186 if (service_id) *service_id = id;
188 return MESSAGEPORT_ERROR_NONE;
197 _find_service (gpointer key, gpointer value, gpointer data)
199 FindServiceData *service_data = (FindServiceData*)data;
200 MsgPortService *service = (MsgPortService *)value;
202 return g_strcmp0 (msgport_service_name (service), service_data->name) == 0
203 && msgport_service_is_trusted (service) == service_data->is_trusted;
208 msgport_manager_register_service (MsgPortManager *manager, const gchar *port_name, gboolean is_trusted, messageport_message_cb message_cb, int *service_id)
210 GError *error = NULL;
211 gchar *object_path = NULL;
212 FindServiceData service_data;
213 MsgPortService *service = NULL;
215 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
216 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
217 g_return_val_if_fail (service_id && port_name && message_cb, MESSAGEPORT_ERROR_INVALID_PARAMETER);
219 /* first check in cached services if found any */
220 service_data.name = port_name;
221 service_data.is_trusted = is_trusted;
222 service = g_hash_table_find (manager->services, _find_service, &service_data);
225 int id = msgport_service_id (service);
226 DBG ("Cached local port found for name '%s:%d' with ID : %d", port_name, is_trusted, id);
228 /* update message handler */
229 msgport_service_set_message_handler (service, message_cb);
232 return MESSAGEPORT_ERROR_NONE;
235 msgport_dbus_glue_manager_call_register_service_sync (manager->proxy,
236 port_name, is_trusted, &object_path, NULL, &error);
239 messageport_error_e err = msgport_daemon_error_to_error (error);
240 WARN ("unable to register service (%s): %s", port_name, error->message);
241 g_error_free (error);
245 return _create_and_cache_service (manager, object_path, message_cb, service_id);
248 static MsgPortService *
249 _get_local_port (MsgPortManager *manager, int service_id)
251 const gchar *object_path = NULL;
252 MsgPortService *service = NULL;
254 object_path = g_hash_table_lookup (manager->local_services, GINT_TO_POINTER(service_id));
255 if (!object_path) return NULL;
257 service = MSGPORT_SERVICE (g_hash_table_lookup (manager->services, object_path));
259 g_hash_table_remove (manager->local_services, GINT_TO_POINTER (service_id));
267 msgport_manager_unregister_servcie (MsgPortManager *manager, int service_id)
269 const gchar *object_path = NULL;
270 MsgPortService *service = NULL;
271 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), FALSE);
272 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
274 service = _get_local_port (manager, service_id);
276 WARN ("No local service found for service id '%d'", service_id);
277 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
280 if (!msgport_service_unregister (service))
281 return MESSAGEPORT_ERROR_IO_ERROR;
283 object_path = (const gchar *)g_hash_table_lookup (manager->local_services,
284 GINT_TO_POINTER(service_id));
285 g_hash_table_remove (manager->local_services, GINT_TO_POINTER(service_id));
286 g_hash_table_remove (manager->services, object_path);
288 return MESSAGEPORT_ERROR_NONE;
292 msgport_manager_check_remote_service (MsgPortManager *manager, const gchar *app_id, const gchar *port, gboolean is_trusted, guint *service_id_out)
294 GError *error = NULL;
295 guint remote_service_id = 0;
297 if (service_id_out) *service_id_out = 0;
299 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
300 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
301 g_return_val_if_fail (app_id && port, MESSAGEPORT_ERROR_INVALID_PARAMETER);
303 if (!app_id || !port) return MESSAGEPORT_ERROR_INVALID_PARAMETER;
305 msgport_dbus_glue_manager_call_check_for_remote_service_sync (manager->proxy,
306 app_id, port, is_trusted, &remote_service_id, NULL, &error);
309 messageport_error_e err = msgport_daemon_error_to_error (error);
310 WARN ("No %sservice found for app_id %s, port name %s: %s",
311 is_trusted ? "trusted " : "", app_id, port, error->message);
312 g_error_free (error);
316 DBG ("Got service id %d for %s, %s", remote_service_id, app_id, port);
317 if (service_id_out) *service_id_out = remote_service_id;
320 return MESSAGEPORT_ERROR_NONE;
324 msgport_manager_get_service_name (MsgPortManager *manager, int service_id, gchar **name_out)
326 MsgPortService *service = NULL;
327 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
328 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
329 g_return_val_if_fail (name_out && service_id, MESSAGEPORT_ERROR_INVALID_PARAMETER);
331 service = _get_local_port (manager, service_id);
332 if (!service) return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
334 *name_out = g_strdup (msgport_service_name (service));
336 return MESSAGEPORT_ERROR_NONE;
340 msgport_manager_get_service_is_trusted (MsgPortManager *manager, int service_id, gboolean *is_trusted_out)
342 MsgPortService *service = NULL;
343 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
344 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
345 g_return_val_if_fail (service_id && is_trusted_out, MESSAGEPORT_ERROR_INVALID_PARAMETER);
347 service = _get_local_port (manager, service_id);
348 if (!service) return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
350 *is_trusted_out = msgport_service_is_trusted (service);
352 return MESSAGEPORT_ERROR_NONE;
356 msgport_manager_send_message (MsgPortManager *manager, const gchar *remote_app_id, const gchar *remote_port, gboolean is_trusted, GVariant *data)
358 guint service_id = 0;
359 GError *error = NULL;
360 messageport_error_e err;
362 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
363 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
364 g_return_val_if_fail (remote_app_id && remote_port, MESSAGEPORT_ERROR_INVALID_PARAMETER);
366 err = msgport_manager_check_remote_service (manager, remote_app_id, remote_port, is_trusted, &service_id);
367 if (service_id == 0) return err;
369 msgport_dbus_glue_manager_call_send_message_sync (manager->proxy, service_id, data, NULL, &error);
372 err = msgport_daemon_error_to_error (error);
373 WARN ("Failed to send message to (%s:%s) : %s", remote_app_id, remote_port, error->message);
374 g_error_free (error);
378 return MESSAGEPORT_ERROR_NONE;
382 msgport_manager_send_bidirectional_message (MsgPortManager *manager, int local_port_id, const gchar *remote_app_id, const gchar *remote_port, gboolean is_trusted, GVariant *data)
384 MsgPortService *service = NULL;
385 guint remote_service_id = 0;
386 messageport_error_e res = 0;
388 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
389 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
390 g_return_val_if_fail (local_port_id > 0 && remote_app_id && remote_port, MESSAGEPORT_ERROR_INVALID_PARAMETER);
392 service = _get_local_port (manager, local_port_id);
394 WARN ("No local service found for service id '%d'", local_port_id);
395 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
398 if ((res = msgport_manager_check_remote_service (manager, remote_app_id, remote_port, is_trusted, &remote_service_id) != MESSAGEPORT_ERROR_NONE)) {
399 WARN ("No remote %sport informatuon for %s:%s, error : %d", is_trusted ? "trusted " : "", remote_app_id, remote_port, res);
400 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
403 DBG ("Sending message from local service '%p' to remote sercie id '%d'", service, remote_service_id);
404 return msgport_service_send_message (service, remote_service_id, data);