1 /* vi:set et ai sw=2 sts=2 ts=2: */
3 * Copyright (c) 2012 GENIVI.
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/.
14 #include <glib-object.h>
19 #include <common/nsm-consumer-dbus.h>
20 #include <common/shutdown-consumer-dbus.h>
22 #include <nsm-dummy/nsm-consumer-service.h>
25 DLT_IMPORT_CONTEXT (nsm_dummy_context);
29 /* property identifiers */
38 typedef struct _NSMShutdownClient NSMShutdownClient;
42 static void nsm_consumer_service_finalize (GObject *object);
43 static void nsm_consumer_service_get_property (GObject *object,
47 static void nsm_consumer_service_set_property (GObject *object,
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,
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,
63 NSMConsumerService *service);
64 static void nsm_shutdown_client_release (NSMShutdownClient *shutdown_client);
68 struct _NSMConsumerServiceClass
70 GObjectClass __parent__;
73 struct _NSMConsumerService
77 NSMConsumer *interface;
78 GDBusConnection *connection;
80 GList *shutdown_clients;
83 struct _NSMShutdownClient
93 G_DEFINE_TYPE (NSMConsumerService, nsm_consumer_service, G_TYPE_OBJECT);
98 nsm_consumer_service_class_init (NSMConsumerServiceClass *klass)
100 GObjectClass *gobject_class;
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;
107 g_object_class_install_property (gobject_class,
109 g_param_spec_object ("connection",
112 G_TYPE_DBUS_CONNECTION,
114 G_PARAM_CONSTRUCT_ONLY |
115 G_PARAM_STATIC_STRINGS));
121 nsm_consumer_service_init (NSMConsumerService *service)
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;
127 service->interface = nsm_consumer_skeleton_new ();
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),
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),
143 nsm_consumer_service_finalize (GObject *object)
145 NSMConsumerService *service = NSM_CONSUMER_SERVICE (object);
147 /* release the D-Bus connection object */
148 if (service->connection != NULL)
149 g_object_unref (service->connection);
151 /* release the interface skeleton */
152 g_signal_handlers_disconnect_matched (service->interface,
154 0, 0, NULL, NULL, service);
155 g_object_unref (service->interface);
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);
162 (*G_OBJECT_CLASS (nsm_consumer_service_parent_class)->finalize) (object);
168 nsm_consumer_service_get_property (GObject *object,
173 NSMConsumerService *service = NSM_CONSUMER_SERVICE (object);
177 case PROP_CONNECTION:
178 g_value_set_object (value, service->connection);
181 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
189 nsm_consumer_service_set_property (GObject *object,
194 NSMConsumerService *service = NSM_CONSUMER_SERVICE (object);
198 case PROP_CONNECTION:
199 service->connection = g_value_dup_object (value);
202 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
210 nsm_consumer_service_handle_register_shutdown_client (NSMConsumer *object,
211 GDBusMethodInvocation *invocation,
212 const gchar *bus_name,
213 const gchar *object_name,
216 NSMConsumerService *service)
218 NSMShutdownClient *shutdown_client = NULL;
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);
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;
232 /* register the shutdown client */
233 service->shutdown_clients = g_list_append (service->shutdown_clients,
234 (gpointer) shutdown_client);
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);
243 DLT_LOG (nsm_dummy_context, DLT_LOG_INFO, DLT_STRING (message));
244 g_slice_free (gchar, message);
246 /* notify the caller that we have handled the register request */
247 nsm_consumer_complete_register_shutdown_client (object, invocation, 0);
254 nsm_consumer_service_handle_unregister_shutdown_client (NSMConsumer *object,
255 GDBusMethodInvocation *invocation,
256 const gchar *bus_name,
257 const gchar *object_name,
259 NSMConsumerService *service)
261 NSMShutdownClient *shutdown_client = NULL;
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);
269 /* find the shutdown client in the list */
270 for (clients = service->shutdown_clients;
271 shutdown_client == NULL && clients != NULL;
272 clients = clients->next)
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))
278 shutdown_client = clients->data;
282 /* unregister the shutdown client */
283 if (shutdown_client != NULL)
285 /* log the unregistered shutdown client */
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);
292 DLT_LOG (nsm_dummy_context, DLT_LOG_INFO, DLT_STRING (message));
293 g_slice_free (gchar, message);
295 /* take out the client from the list */
296 service->shutdown_clients =
297 g_list_remove (service->shutdown_clients, shutdown_client);
299 /* release the client */
300 nsm_shutdown_client_release (shutdown_client);
304 /* notify the caller that we have handled the unregister request */
305 nsm_consumer_complete_un_register_shutdown_client (object, invocation, -1);
309 /* notify the caller that we have handled the unregister request */
310 nsm_consumer_complete_un_register_shutdown_client (object, invocation, 0);
317 nsm_consumer_service_new (GDBusConnection *connection)
319 g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
320 return g_object_new (NSM_CONSUMER_TYPE_SERVICE, "connection", connection, NULL);
326 nsm_consumer_service_start (NSMConsumerService *service,
329 g_return_val_if_fail (NSM_CONSUMER_IS_SERVICE (service), FALSE);
330 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
332 /* announce the Consumer service on the bus */
333 return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service->interface),
335 "/com/contiautomotive/NodeStateManager/Consumer",
342 nsm_shutdown_client_release (NSMShutdownClient *shutdown_client)
344 g_return_if_fail (shutdown_client != NULL);
346 /* release the client fields */
347 g_slice_free (gchar, shutdown_client->bus_name);
348 g_slice_free (gchar, shutdown_client->object_name);
350 /* release the client */
351 g_slice_free (NSMShutdownClient, shutdown_client);
357 nsm_consumer_service_shutdown_consumers (NSMConsumerService *service)
359 ShutdownConsumer *proxy = NULL;
360 GError *error = NULL;
363 GList *shutdown_consumers;
366 g_return_if_fail (NSM_CONSUMER_IS_SERVICE (service));
368 /* reverse the list of clients */
369 shutdown_consumers = g_list_reverse (service->shutdown_clients);
371 for (clients = shutdown_consumers;
373 clients = clients->next)
375 /* create a synchronous proxy; the NSM has to wait
376 * the shutting down reponse from Boot Manager */
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,
387 g_strdup_printf ("Failed to connect to nsm consumer service: %s",
389 DLT_LOG (nsm_dummy_context, DLT_LOG_ERROR, DLT_STRING (message));
390 g_slice_free (gchar, message);
391 g_error_free (error);
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,
400 g_strdup_printf ("Failed to call shutdown method: %s",
402 DLT_LOG (nsm_dummy_context, DLT_LOG_ERROR, DLT_STRING (message));
403 g_slice_free (gchar, message);
404 g_error_free (error);
407 /* log the shutdown client */
409 g_strdup_printf ("Shutdown client information: Bus %s : Object: %s\
411 ((NSMShutdownClient *) clients->data)->bus_name,
412 ((NSMShutdownClient *) clients->data)->object_name,
413 ((NSMShutdownClient *) clients->data)->shutdown_mode);
415 DLT_LOG (nsm_dummy_context, DLT_LOG_INFO, DLT_STRING (message));
416 g_slice_free (gchar, message);
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);
422 nsm_shutdown_client_release ((NSMShutdownClient *) clients->data);
424 /* release the proxy */
425 g_object_unref (proxy);