1 #include "msgport-manager.h"
2 #include "msgport-service.h"
3 #include "msgport-utils.h" /* msgport_daemon_error_to_error */
4 #include "message-port.h" /* messageport_error_e */
5 #include "common/dbus-manager-glue.h"
6 #include "common/log.h"
7 #include "config.h" /* MESSAGEPORT_BUS_ADDRESS */
10 struct _MsgPortManager
14 MsgPortDbusGlueManager *proxy;
15 GHashTable *services; /* {gchar*:MsgPortService*} */
16 GHashTable *local_services; /* {gint: gchar *} */
17 GHashTable *remote_services; /* {gint: gchar *} */
20 G_DEFINE_TYPE (MsgPortManager, msgport_manager, G_TYPE_OBJECT)
23 _unregister_service_cb (int service_id, const gchar *object_path, MsgPortManager *manager)
25 MsgPortService *service = g_hash_table_lookup (manager->services, object_path);
27 if (service) msgport_service_unregister (service);
31 _finalize (GObject *self)
33 MsgPortManager *manager = MSGPORT_MANAGER (self);
35 if (manager->local_services) {
36 g_hash_table_unref (manager->local_services);
37 manager->local_services = NULL;
40 if (manager->remote_services) {
41 g_hash_table_unref (manager->remote_services);
42 manager->remote_services = NULL;
45 G_OBJECT_CLASS (msgport_manager_parent_class)->finalize (self);
49 _dispose (GObject *self)
51 MsgPortManager *manager = MSGPORT_MANAGER (self);
53 g_hash_table_foreach (manager->local_services, (GHFunc)_unregister_service_cb, manager);
55 if (manager->services) {
56 g_hash_table_unref (manager->services);
57 manager->services = NULL;
60 g_clear_object (&manager->proxy);
62 G_OBJECT_CLASS (msgport_manager_parent_class)->dispose (self);
66 msgport_manager_class_init (MsgPortManagerClass *klass)
68 GObjectClass *g_klass = G_OBJECT_CLASS (klass);
70 g_klass->finalize = _finalize;
71 g_klass->dispose = _dispose;
75 msgport_manager_init (MsgPortManager *manager)
78 GDBusConnection *connection = NULL;
79 gchar *bus_address = g_strdup_printf (MESSAGEPORT_BUS_ADDRESS);
81 manager->services = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
82 manager->local_services = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
83 manager->remote_services = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
85 connection = g_dbus_connection_new_for_address_sync (bus_address,
86 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, &error);
88 WARN ("Fail to connect messageport server at address %s: %s", bus_address, error->message);
92 manager->proxy = msgport_dbus_glue_manager_proxy_new_sync (
93 connection, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, "/", NULL, &error);
95 WARN ("Fail to get manager proxy : %s", error->message);
101 MsgPortManager * msgport_manager_new ()
103 return g_object_new (MSGPORT_TYPE_MANAGER, NULL);
106 static MsgPortManager *__manager;
108 MsgPortManager * msgport_get_manager ()
111 __manager = msgport_manager_new ();
117 static messageport_error_e
118 _create_and_cache_service (MsgPortManager *manager, gchar *object_path, messageport_message_cb cb, int *service_id)
121 MsgPortService *service = msgport_service_new (
122 g_dbus_proxy_get_connection (G_DBUS_PROXY(manager->proxy)),
125 g_free (object_path);
126 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
129 id = msgport_service_id (service);
131 g_hash_table_insert (manager->services, object_path, service);
132 g_hash_table_insert (manager->local_services, GINT_TO_POINTER (id), object_path);
134 if (service_id) *service_id = id;
136 return MESSAGEPORT_ERROR_NONE;
140 msgport_manager_register_service (MsgPortManager *manager, const gchar *port_name, gboolean is_trusted, messageport_message_cb message_cb, int *service_id)
142 GError *error = NULL;
143 gchar *object_path = NULL;
145 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
146 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
147 g_return_val_if_fail (service_id && port_name && message_cb, MESSAGEPORT_ERROR_INVALID_PARAMETER);
149 msgport_dbus_glue_manager_call_register_service_sync (manager->proxy,
150 port_name, is_trusted, &object_path, NULL, &error);
153 messageport_error_e err = msgport_daemon_error_to_error (error);
154 WARN ("unable to register service (%s): %s", port_name, error->message);
155 g_error_free (error);
159 return _create_and_cache_service (manager, object_path, message_cb, service_id);
162 static MsgPortService *
163 _get_local_port (MsgPortManager *manager, int service_id)
165 const gchar *object_path = NULL;
166 MsgPortService *service = NULL;
168 object_path = g_hash_table_lookup (manager->local_services, GINT_TO_POINTER(service_id));
169 if (!object_path) return NULL;
171 service = MSGPORT_SERVICE (g_hash_table_lookup (manager->services, object_path));
173 g_hash_table_remove (manager->local_services, GINT_TO_POINTER (service_id));
181 msgport_manager_unregister_servcie (MsgPortManager *manager, int service_id)
183 const gchar *object_path = NULL;
184 MsgPortService *service = NULL;
185 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), FALSE);
186 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
188 service = _get_local_port (manager, service_id);
190 WARN ("No local service found for service id '%d'", service_id);
191 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
194 if (!msgport_service_unregister (service))
195 return MESSAGEPORT_ERROR_IO_ERROR;
197 object_path = (const gchar *)g_hash_table_lookup (manager->local_services,
198 GINT_TO_POINTER(service_id));
199 g_hash_table_remove (manager->local_services, GINT_TO_POINTER(service_id));
200 g_hash_table_remove (manager->services, object_path);
202 return MESSAGEPORT_ERROR_NONE;
206 msgport_manager_check_remote_service (MsgPortManager *manager, const gchar *app_id, const gchar *port, gboolean is_trusted, guint *service_id_out)
208 GError *error = NULL;
209 guint remote_service_id = 0;
211 if (service_id_out) *service_id_out = 0;
213 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
214 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
215 g_return_val_if_fail (app_id && port, MESSAGEPORT_ERROR_INVALID_PARAMETER);
217 if (!app_id || !port) return MESSAGEPORT_ERROR_INVALID_PARAMETER;
219 msgport_dbus_glue_manager_call_check_for_remote_service_sync (manager->proxy,
220 app_id, port, is_trusted, &remote_service_id, NULL, &error);
223 messageport_error_e err = msgport_daemon_error_to_error (error);
224 WARN ("No %sservice found for app_id %s, port name %s: %s",
225 is_trusted ? "trusted " : "", app_id, port, error->message);
226 g_error_free (error);
230 DBG ("Got service id %d for %s, %s", remote_service_id, app_id, port);
231 if (service_id_out) *service_id_out = remote_service_id;
234 return MESSAGEPORT_ERROR_NONE;
238 msgport_manager_get_service_name (MsgPortManager *manager, int service_id, gchar **name_out)
240 MsgPortService *service = NULL;
241 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
242 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
243 g_return_val_if_fail (name_out && service_id, MESSAGEPORT_ERROR_INVALID_PARAMETER);
245 service = _get_local_port (manager, service_id);
246 if (!service) return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
248 *name_out = g_strdup (msgport_service_name (service));
249 DBG ("PORT NAME : %s", *name_out);
251 return MESSAGEPORT_ERROR_NONE;
255 msgport_manager_send_message (MsgPortManager *manager, const gchar *remote_app_id, const gchar *remote_port, gboolean is_trusted, GVariant *data)
257 guint service_id = 0;
258 GError *error = NULL;
259 messageport_error_e err;
261 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
262 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
263 g_return_val_if_fail (remote_app_id && remote_port, MESSAGEPORT_ERROR_INVALID_PARAMETER);
265 err = msgport_manager_check_remote_service (manager, remote_app_id, remote_port, is_trusted, &service_id);
266 if (service_id == 0) return err;
268 msgport_dbus_glue_manager_call_send_message_sync (manager->proxy, service_id, data, NULL, &error);
271 err = msgport_daemon_error_to_error (error);
272 WARN ("Failed to send message to (%s:%s) : %s", remote_app_id, remote_port, error->message);
273 g_error_free (error);
277 return MESSAGEPORT_ERROR_NONE;
281 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)
283 MsgPortService *service = NULL;
284 guint remote_service_id = 0;
285 messageport_error_e res = 0;
287 g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
288 g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
289 g_return_val_if_fail (local_port_id > 0 && remote_app_id && remote_port, MESSAGEPORT_ERROR_INVALID_PARAMETER);
291 service = _get_local_port (manager, local_port_id);
293 WARN ("No local service found for service id '%d'", local_port_id);
294 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
297 if ((res = msgport_manager_check_remote_service (manager, remote_app_id, remote_port, is_trusted, &remote_service_id) != MESSAGEPORT_ERROR_NONE)) {
298 WARN ("No remote %sport informatuon for %s:%s, error : %d", is_trusted ? "trusted " : "", remote_app_id, remote_port, res);
299 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
302 DBG ("Sending message from local service '%p' to remote sercie id '%d'", service, remote_service_id);
303 return msgport_service_send_message (service, remote_service_id, data);