Drop GApplication, fix D-Bus activation, further NSM integration work
[profile/ivi/node-startup-controller.git] / nsm-dummy / nsm-consumer-service.c
1 /* vi:set et ai sw=2 sts=2 ts=2: */
2 /* -
3  * Copyright (c) 2012 GENIVI.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <glib-object.h>
15 #include <gio/gio.h>
16
17 #include <dlt/dlt.h>
18
19 #include <common/nsm-consumer-dbus.h>
20 #include <common/shutdown-consumer-dbus.h>
21
22 #include <nsm-dummy/nsm-consumer-service.h>
23
24
25 DLT_IMPORT_CONTEXT (nsm_dummy_context);
26
27
28
29 /* property identifiers */
30 enum
31 {
32   PROP_0,
33   PROP_CONNECTION,
34 };
35
36
37
38 typedef struct _NSMShutdownClient NSMShutdownClient;
39
40
41
42 static void     nsm_consumer_service_finalize                          (GObject               *object);
43 static void     nsm_consumer_service_get_property                      (GObject               *object,
44                                                                         guint                  prop_id,
45                                                                         GValue                *value,
46                                                                         GParamSpec            *pspec);
47 static void     nsm_consumer_service_set_property                      (GObject               *object,
48                                                                         guint                  prop_id,
49                                                                         const GValue          *value,
50                                                                         GParamSpec            *pspec);
51 static gboolean nsm_consumer_service_handle_register_shutdown_client   (NSMConsumer           *object,
52                                                                         GDBusMethodInvocation *invocation,
53                                                                         const gchar           *bus_name,
54                                                                         const gchar           *object_name,
55                                                                         gint                   shutdown_mode,
56                                                                         guint                  timeout_ms,
57                                                                         NSMConsumerService    *service);
58 static gboolean nsm_consumer_service_handle_unregister_shutdown_client (NSMConsumer           *object,
59                                                                         GDBusMethodInvocation *invocation,
60                                                                         const gchar           *bus_name,
61                                                                         const gchar           *object_name,
62                                                                         gint                   shutdown_mode,
63                                                                         NSMConsumerService    *service);
64 static void     nsm_shutdown_client_release                            (NSMShutdownClient     *shutdown_client);
65
66
67
68 struct _NSMConsumerServiceClass
69 {
70   GObjectClass __parent__;
71 };
72
73 struct _NSMConsumerService
74 {
75   GObject          __parent__;
76
77   NSMConsumer     *interface;
78   GDBusConnection *connection;
79
80   GList           *shutdown_clients;
81 };
82
83 struct _NSMShutdownClient
84 {
85   gchar *bus_name;
86   gchar *object_name;
87   guint  timeout_ms;
88   gint   shutdown_mode;
89 };
90
91
92
93 G_DEFINE_TYPE (NSMConsumerService, nsm_consumer_service, G_TYPE_OBJECT);
94
95
96
97 static void
98 nsm_consumer_service_class_init (NSMConsumerServiceClass *klass)
99 {
100   GObjectClass *gobject_class;
101
102   gobject_class = G_OBJECT_CLASS (klass);
103   gobject_class->finalize = nsm_consumer_service_finalize;
104   gobject_class->get_property = nsm_consumer_service_get_property;
105   gobject_class->set_property = nsm_consumer_service_set_property;
106
107   g_object_class_install_property (gobject_class,
108                                    PROP_CONNECTION,
109                                    g_param_spec_object ("connection",
110                                                         "connection",
111                                                         "connection",
112                                                         G_TYPE_DBUS_CONNECTION,
113                                                         G_PARAM_READWRITE |
114                                                         G_PARAM_CONSTRUCT_ONLY |
115                                                         G_PARAM_STATIC_STRINGS));
116 }
117
118
119
120 static void
121 nsm_consumer_service_init (NSMConsumerService *service)
122 {
123   /* create a list of shutdown consumers; we will use this to shut down
124    * the consumers in reverse order of consumer registrations */
125   service->shutdown_clients = NULL;
126
127   service->interface = nsm_consumer_skeleton_new ();
128
129   /* implement the RegisterShutdownClient() handler */
130   g_signal_connect (service->interface, "handle-register-shutdown-client",
131                     G_CALLBACK (nsm_consumer_service_handle_register_shutdown_client),
132                     service);
133
134   /* implement the UnRegisterShutdownClient() handler */
135   g_signal_connect (service->interface, "handle-un-register-shutdown-client",
136                     G_CALLBACK (nsm_consumer_service_handle_unregister_shutdown_client),
137                     service);
138 }
139
140
141
142 static void
143 nsm_consumer_service_finalize (GObject *object)
144 {
145   NSMConsumerService *service = NSM_CONSUMER_SERVICE (object);
146
147   /* release the D-Bus connection object */
148   if (service->connection != NULL)
149     g_object_unref (service->connection);
150
151   /* release the interface skeleton */
152   g_signal_handlers_disconnect_matched (service->interface,
153                                         G_SIGNAL_MATCH_DATA,
154                                         0, 0, NULL, NULL, service);
155   g_object_unref (service->interface);
156
157   /* release the list of shutdown clients */
158   if (service->shutdown_clients != NULL)
159     g_list_free_full (service->shutdown_clients,
160                       (GDestroyNotify) nsm_shutdown_client_release);
161
162   (*G_OBJECT_CLASS (nsm_consumer_service_parent_class)->finalize) (object);
163 }
164
165
166
167 static void
168 nsm_consumer_service_get_property (GObject    *object,
169                                    guint       prop_id,
170                                    GValue     *value,
171                                    GParamSpec *pspec)
172 {
173   NSMConsumerService *service = NSM_CONSUMER_SERVICE (object);
174
175   switch (prop_id)
176     {
177     case PROP_CONNECTION:
178       g_value_set_object (value, service->connection);
179       break;
180     default:
181       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
182       break;
183     }
184 }
185
186
187
188 static void
189 nsm_consumer_service_set_property (GObject      *object,
190                                    guint         prop_id,
191                                    const GValue *value,
192                                    GParamSpec   *pspec)
193 {
194   NSMConsumerService *service = NSM_CONSUMER_SERVICE (object);
195
196   switch (prop_id)
197     {
198     case PROP_CONNECTION:
199       service->connection = g_value_dup_object (value);
200       break;
201     default:
202       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
203       break;
204     }
205 }
206
207
208
209 static gboolean
210 nsm_consumer_service_handle_register_shutdown_client (NSMConsumer           *object,
211                                                       GDBusMethodInvocation *invocation,
212                                                       const gchar           *bus_name,
213                                                       const gchar           *object_name,
214                                                       gint                   shutdown_mode,
215                                                       guint                  timeout_ms,
216                                                       NSMConsumerService    *service)
217 {
218   NSMShutdownClient *shutdown_client = NULL;
219   gchar             *message;
220
221   g_return_val_if_fail (IS_NSM_CONSUMER (object), FALSE);
222   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
223   g_return_val_if_fail (NSM_CONSUMER_IS_SERVICE (service), FALSE);
224
225   /* create the shutdown client */
226   shutdown_client = g_slice_new0 (NSMShutdownClient);
227   shutdown_client->bus_name = g_strdup (bus_name);
228   shutdown_client->object_name = g_strdup (object_name);
229   shutdown_client->timeout_ms = timeout_ms;
230   shutdown_client->shutdown_mode = shutdown_mode;
231
232   /* register the shutdown client */
233   service->shutdown_clients = g_list_append (service->shutdown_clients,
234                                              (gpointer) shutdown_client);
235
236   /* log the registered shutdown client */
237   message = g_strdup_printf ("registered client information: Bus %s : Object: %s\
238                               Shutdown mode: %d Timeout: %d", shutdown_client->bus_name,
239                               shutdown_client->object_name,
240                               shutdown_client->shutdown_mode,
241                               shutdown_client->timeout_ms);
242
243   DLT_LOG (nsm_dummy_context, DLT_LOG_INFO, DLT_STRING (message));
244   g_slice_free (gchar, message);
245
246   /* notify the caller that we have handled the register request */
247   nsm_consumer_complete_register_shutdown_client (object, invocation, 0);
248   return TRUE;
249 }
250
251
252
253 static gboolean
254 nsm_consumer_service_handle_unregister_shutdown_client (NSMConsumer           *object,
255                                                         GDBusMethodInvocation *invocation,
256                                                         const gchar           *bus_name,
257                                                         const gchar           *object_name,
258                                                         gint                   shutdown_mode,
259                                                         NSMConsumerService    *service)
260 {
261   NSMShutdownClient *shutdown_client = NULL;
262   GList             *clients;
263   gchar             *message;
264
265   g_return_val_if_fail (IS_NSM_CONSUMER (object), FALSE);
266   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
267   g_return_val_if_fail (NSM_CONSUMER_IS_SERVICE (service), FALSE);
268
269   /* find the shutdown client in the list */
270   for (clients = service->shutdown_clients;
271        shutdown_client == NULL && clients != NULL;
272        clients = clients->next)
273     {
274       if ((g_strcmp0 (((NSMShutdownClient *) clients->data)->bus_name, bus_name) == 0)
275           && (g_strcmp0 (((NSMShutdownClient *) clients->data)->object_name, object_name) == 0)
276           && (((NSMShutdownClient *) clients->data)->shutdown_mode == shutdown_mode))
277         {
278           shutdown_client = clients->data;
279         }
280     }
281
282   /* unregister the shutdown client */
283   if (shutdown_client != NULL)
284     {
285         /* log the unregistered shutdown client */
286         message = 
287             g_strdup_printf ("unregistered client information: Bus %s : Object: %s\
288                               Shutdown mode: %d", shutdown_client->bus_name,
289                               shutdown_client->object_name,
290                               shutdown_client->shutdown_mode);
291
292         DLT_LOG (nsm_dummy_context, DLT_LOG_INFO, DLT_STRING (message));
293         g_slice_free (gchar, message);
294
295        /* take out the client from the list */
296        service->shutdown_clients = 
297          g_list_remove (service->shutdown_clients, shutdown_client);
298
299        /* release the client */
300       nsm_shutdown_client_release (shutdown_client);
301     }
302   else
303     {
304       /* notify the caller that we have handled the unregister request */
305       nsm_consumer_complete_un_register_shutdown_client (object, invocation, -1);
306       return TRUE;
307     }
308
309   /* notify the caller that we have handled the unregister request */
310   nsm_consumer_complete_un_register_shutdown_client (object, invocation, 0);
311   return TRUE;
312 }
313
314
315
316 NSMConsumerService *
317 nsm_consumer_service_new (GDBusConnection *connection)
318 {
319   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
320   return g_object_new (NSM_CONSUMER_TYPE_SERVICE, "connection", connection, NULL);
321 }
322
323
324
325 gboolean
326 nsm_consumer_service_start (NSMConsumerService *service,
327                             GError            **error)
328 {
329   g_return_val_if_fail (NSM_CONSUMER_IS_SERVICE (service), FALSE);
330   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
331
332   /* announce the Consumer service on the bus */
333   return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service->interface),
334                                            service->connection,
335                                            "/com/contiautomotive/NodeStateManager/Consumer",
336                                            error);
337 }
338
339
340
341 static void
342 nsm_shutdown_client_release (NSMShutdownClient *shutdown_client)
343 {
344   g_return_if_fail (shutdown_client != NULL);
345
346   /* release the client fields */
347   g_slice_free (gchar, shutdown_client->bus_name);
348   g_slice_free (gchar, shutdown_client->object_name);
349
350   /* release the client */
351   g_slice_free (NSMShutdownClient, shutdown_client);
352 }
353
354
355
356 void
357 nsm_consumer_service_shutdown_consumers (NSMConsumerService *service)
358 {
359   ShutdownConsumer *proxy = NULL;
360   GError           *error = NULL;
361   gchar            *message;
362   GList            *clients;
363   GList            *shutdown_consumers;
364   gint              error_code;
365
366   g_return_if_fail (NSM_CONSUMER_IS_SERVICE (service));
367
368   /* reverse the list of clients */
369   shutdown_consumers = g_list_reverse (service->shutdown_clients);
370
371   for (clients = shutdown_consumers;
372        clients != NULL;
373        clients = clients->next)
374     {
375       /* create a synchronous proxy; the NSM has to wait
376        * the shutting down reponse from Boot Manager */
377       proxy =
378         shutdown_consumer_proxy_new_sync (service->connection,
379                                           G_DBUS_PROXY_FLAGS_NONE,
380                                           ((NSMShutdownClient *) clients->data)->bus_name,
381                                           ((NSMShutdownClient *) clients->data)->object_name,
382                                           NULL,
383                                           &error);
384       if (error != NULL)
385         {
386           message =
387             g_strdup_printf ("Failed to connect to nsm consumer service: %s",
388                              error->message);
389           DLT_LOG (nsm_dummy_context, DLT_LOG_ERROR, DLT_STRING (message));
390           g_slice_free (gchar, message);
391           g_error_free (error);
392         }
393
394       /* call the shutdown method (temporarily using bald numbers instead of enums) */
395       shutdown_consumer_call_lifecycle_request_sync (proxy, 1, 1234, &error_code, NULL,
396                                                      &error);
397       if (error != NULL)
398         {
399           message = 
400             g_strdup_printf ("Failed to call shutdown method: %s",
401                              error->message);
402           DLT_LOG (nsm_dummy_context, DLT_LOG_ERROR, DLT_STRING (message));
403           g_slice_free (gchar, message);
404           g_error_free (error);
405         }
406
407       /* log the shutdown client */
408         message =
409             g_strdup_printf ("Shutdown client information: Bus %s : Object: %s\
410                               Shutdown mode: %d", 
411                              ((NSMShutdownClient *) clients->data)->bus_name,
412                              ((NSMShutdownClient *) clients->data)->object_name,
413                              ((NSMShutdownClient *) clients->data)->shutdown_mode);
414
415         DLT_LOG (nsm_dummy_context, DLT_LOG_INFO, DLT_STRING (message));
416         g_slice_free (gchar, message);
417
418       /* take out the shutdown client from the list and release it */
419         service->shutdown_clients = 
420           g_list_remove (service->shutdown_clients, (NSMShutdownClient *) clients->data);
421
422         nsm_shutdown_client_release ((NSMShutdownClient *) clients->data);
423
424       /* release the proxy */
425         g_object_unref (proxy);
426     }
427 }