certifiacte validation code added
[profile/ivi/message-port.git] / lib / msgport-manager.c
1 #include "msgport-manager.h"
2 #include "msgport-service.h"
3 #include "message-port.h" /* messageport_error_e */
4 #include "common/dbus-manager-glue.h"
5 #include "common/log.h"
6 #include "config.h" /* MESSAGEPORT_BUS_ADDRESS */
7 #include <gio/gio.h>
8
9 struct _MsgPortManager
10 {
11     GObject parent;
12
13     MsgPortDbusGlueManager *proxy;
14     GHashTable *services; /* {gchar*:MsgPortService*} */
15     GHashTable *local_services; /* {gint: gchar *} */ 
16     GHashTable *remote_services; /* {gint: gchar *} */
17 };
18
19 G_DEFINE_TYPE (MsgPortManager, msgport_manager, G_TYPE_OBJECT)
20
21 static void
22 _unregister_service_cb (int service_id, const gchar *object_path, MsgPortManager *manager)
23 {
24     MsgPortService *service = g_hash_table_lookup (manager->services, object_path);
25
26     if (service) msgport_service_unregister (service);
27 }
28
29 static void
30 _finalize (GObject *self)
31 {
32     MsgPortManager *manager = MSGPORT_MANAGER (self);
33
34     if (manager->local_services) {
35         g_hash_table_unref (manager->local_services);
36         manager->local_services = NULL;
37     }
38
39     if (manager->remote_services) {
40         g_hash_table_unref (manager->remote_services);
41         manager->remote_services = NULL;
42     }
43
44     G_OBJECT_CLASS (msgport_manager_parent_class)->finalize (self);
45 }
46
47 static void
48 _dispose (GObject *self)
49 {
50     MsgPortManager *manager = MSGPORT_MANAGER (self);
51
52     g_hash_table_foreach (manager->local_services, (GHFunc)_unregister_service_cb, manager);
53
54     if (manager->services) {
55         g_hash_table_unref (manager->services);
56         manager->services = NULL;
57     }
58
59     g_clear_object (&manager->proxy);
60
61     G_OBJECT_CLASS (msgport_manager_parent_class)->dispose (self);
62 }
63
64 static void
65 msgport_manager_class_init (MsgPortManagerClass *klass)
66 {
67     GObjectClass *g_klass = G_OBJECT_CLASS (klass);
68
69     g_klass->finalize = _finalize;
70     g_klass->dispose = _dispose;
71 }
72
73 static void
74 msgport_manager_init (MsgPortManager *manager)
75 {
76     GError          *error = NULL;
77     GDBusConnection *connection = NULL;
78     gchar           *bus_address = g_strdup_printf (MESSAGEPORT_BUS_ADDRESS);
79
80     manager->services = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
81     manager->local_services = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
82     manager->remote_services = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
83
84     connection = g_dbus_connection_new_for_address_sync (bus_address,
85             G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, &error);
86     if (error) {
87         WARN ("Fail to connect messageport server at address %s: %s", bus_address, error->message);
88         g_error_free (error);
89     }
90     else {
91         manager->proxy = msgport_dbus_glue_manager_proxy_new_sync (
92             connection, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, "/", NULL, &error);
93         if (error) {
94             WARN ("Fail to get manager proxy : %s", error->message);
95             g_error_free (error);
96         }
97     }
98 }
99
100 MsgPortManager * msgport_manager_new ()
101 {
102     return g_object_new (MSGPORT_TYPE_MANAGER, NULL);
103 }
104
105 static MsgPortManager *__manager;
106
107 MsgPortManager * msgport_get_manager () 
108 {
109     if (!__manager) {
110         __manager = msgport_manager_new ();
111     }
112
113     return __manager;
114 }
115
116 static int
117 _create_and_cache_service (MsgPortManager *manager, gchar *object_path, messageport_message_cb cb)
118 {
119     int id;
120     MsgPortService *service = msgport_service_new (
121             g_dbus_proxy_get_connection (G_DBUS_PROXY(manager->proxy)),
122             object_path, cb);
123     if (!service) {
124         return MESSAGEPORT_ERROR_IO_ERROR;
125     }
126
127     id = msgport_service_id (service);
128
129     g_hash_table_insert (manager->services, object_path, service);
130     g_hash_table_insert (manager->local_services, GINT_TO_POINTER (id), object_path);
131
132     return id;
133 }
134
135 messageport_error_e
136 msgport_manager_register_service (MsgPortManager *manager, const gchar *port_name, gboolean is_trusted, messageport_message_cb message_cb, int *service_id)
137 {
138     GError *error = NULL;
139     gchar *object_path = NULL;
140
141     g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
142     g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
143     g_return_val_if_fail (service_id && port_name && message_cb, MESSAGEPORT_ERROR_INVALID_PARAMETER);
144
145     msgport_dbus_glue_manager_call_register_service_sync (manager->proxy,
146             port_name, is_trusted, &object_path, NULL, &error);
147
148     if (error) {
149         WARN ("unable to register service (%s): %s", port_name, error->message);
150         messageport_error_e res = msgport_daemon_error_to_error(error);
151         g_error_free (error);
152         return res; 
153     }
154
155     *service_id = _create_and_cache_service (manager, object_path, message_cb);
156
157     return MESSAGEPORT_ERROR_NONE;
158 }
159
160 static MsgPortService *
161 _get_local_port (MsgPortManager *manager, int service_id)
162 {
163     const gchar *object_path = NULL;
164     MsgPortService *service = NULL;
165
166     object_path = g_hash_table_lookup (manager->local_services, GINT_TO_POINTER(service_id));
167     if (!object_path) return NULL;
168
169     service = MSGPORT_SERVICE (g_hash_table_lookup (manager->services, object_path));
170     if (!service) {
171         g_hash_table_remove (manager->local_services, GINT_TO_POINTER (service_id));
172         return NULL;
173     }
174
175     return service;
176 }
177
178 messageport_error_e
179 msgport_manager_unregister_servcie (MsgPortManager *manager, int service_id)
180 {
181     const gchar *object_path = NULL;
182     MsgPortService *service = NULL;
183     g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), FALSE);
184     g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
185
186     service = _get_local_port (manager, service_id);
187     if (!service) {
188         WARN ("No local service found for service id '%d'", service_id);
189         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
190     }
191
192     if (!msgport_service_unregister (service)) 
193         return MESSAGEPORT_ERROR_IO_ERROR;
194
195     object_path = (const gchar *)g_hash_table_lookup (manager->local_services,
196                                                       GINT_TO_POINTER(service_id));
197     g_hash_table_remove (manager->local_services, GINT_TO_POINTER(service_id));
198     g_hash_table_remove (manager->services, object_path);
199
200     return MESSAGEPORT_ERROR_NONE;
201 }
202
203 messageport_error_e 
204 msgport_manager_check_remote_service (MsgPortManager *manager, const gchar *app_id, const gchar *port, gboolean is_trusted, guint *service_id_out)
205 {
206     GError *error = NULL;
207     guint remote_service_id = 0;
208
209     if (service_id_out) *service_id_out = 0;
210
211     g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
212     g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
213     g_return_val_if_fail (app_id && port, MESSAGEPORT_ERROR_INVALID_PARAMETER);
214
215     if (!app_id || !port) return MESSAGEPORT_ERROR_INVALID_PARAMETER;
216
217     msgport_dbus_glue_manager_call_check_for_remote_service_sync (manager->proxy,
218             app_id, port, is_trusted, &remote_service_id, NULL, &error);
219
220     if (error) {
221         WARN ("No %sservice found for app_id %s, port name %s: %s", 
222                 is_trusted ? "trusted " : "", app_id, port, error->message);
223         g_error_free (error);
224         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
225     }
226     else {
227         DBG ("Got service id %d for %s, %s", remote_service_id, app_id, port);
228
229         if (service_id_out)  *service_id_out = remote_service_id;
230     }
231
232     return MESSAGEPORT_ERROR_NONE;
233 }
234
235 messageport_error_e
236 msgport_manager_get_service_name (MsgPortManager *manager, int service_id, gchar **name_out)
237 {
238     MsgPortService *service = NULL;
239     g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
240     g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
241     g_return_val_if_fail (name_out && service_id, MESSAGEPORT_ERROR_INVALID_PARAMETER);
242
243     service = _get_local_port (manager, service_id);
244     if (!service) return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
245
246     *name_out = g_strdup (msgport_service_name (service));
247     DBG ("PORT NAME : %s", *name_out);
248
249     return MESSAGEPORT_ERROR_NONE;
250 }
251
252 messageport_error_e
253 msgport_manager_send_message (MsgPortManager *manager, const gchar *remote_app_id, const gchar *remote_port, gboolean is_trusted, GVariant *data)
254 {
255     guint service_id = 0;
256     messageport_error_e res = MESSAGEPORT_ERROR_NONE;
257     GError *error = NULL;
258
259     g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
260     g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
261     g_return_val_if_fail (remote_app_id && remote_port, MESSAGEPORT_ERROR_INVALID_PARAMETER);
262
263     res = msgport_manager_check_remote_service (manager, remote_app_id, remote_port, is_trusted, &service_id);
264     if (service_id == 0) return res;
265
266     msgport_dbus_glue_manager_call_send_message_sync (manager->proxy, service_id, data, NULL, &error);
267
268     if (error) {
269         WARN ("Failed to send message to (%s:%s) : %s", remote_app_id, remote_port, error->message);
270         g_error_free (error);
271         res = MESSAGEPORT_ERROR_IO_ERROR;
272     }
273
274     return res;
275 }
276
277 messageport_error_e
278 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)
279 {
280     MsgPortService *service = NULL;
281     guint remote_service_id = 0;
282     messageport_error_e res = 0;
283
284     g_return_val_if_fail (manager && MSGPORT_IS_MANAGER (manager), MESSAGEPORT_ERROR_IO_ERROR);
285     g_return_val_if_fail (manager->proxy, MESSAGEPORT_ERROR_IO_ERROR);
286     g_return_val_if_fail (local_port_id > 0 && remote_app_id && remote_port, MESSAGEPORT_ERROR_INVALID_PARAMETER);
287
288     service = _get_local_port (manager, local_port_id);
289     if (!service) {
290         WARN ("No local service found for service id '%d'", local_port_id);
291         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
292     }
293     if ( (res = msgport_manager_check_remote_service (manager, remote_app_id, remote_port, is_trusted, &remote_service_id) != MESSAGEPORT_ERROR_NONE)) {
294         WARN ("No remote %sport informatuon for %s:%s, error : %d", is_trusted ? "trusted " : "", remote_app_id, remote_port, res);
295         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
296     }
297
298     DBG ("Sending message from local service '%p' to remote sercie id '%d'", service, remote_service_id);
299     return msgport_service_send_message (service, remote_service_id, data);
300 }
301