Line data Source code
1 : /* SPDX-License-Identifier: Apache-2.0 */
2 : /**
3 : * Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
4 : *
5 : * @file gdbus-util.c
6 : * @date 25 June 2022
7 : * @brief Internal GDbus utility wrapper of Machine Learning agent daemon
8 : * @see https://github.com/nnstreamer/deviceMLOps.MLAgent
9 : * @author Sangjung Woo <sangjung.woo@samsung.com>
10 : * @bug No known bugs except for NYI items
11 : */
12 :
13 : #include <errno.h>
14 : #include <stdbool.h>
15 : #include <systemd/sd-daemon.h>
16 :
17 : #include "gdbus-util.h"
18 : #include "log.h"
19 :
20 : static GDBusConnection *g_dbus_sys_conn = NULL;
21 :
22 : /**
23 : * @brief Export the DBus interface at the Object path on the bus connection.
24 : */
25 : int
26 59 : gdbus_export_interface (gpointer instance, const char *obj_path)
27 : {
28 59 : if (g_dbus_sys_conn == NULL) {
29 2 : ml_loge ("Cannot get the dbus connection to the system message bus");
30 2 : return -ENOSYS;
31 : }
32 :
33 57 : if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (instance),
34 : g_dbus_sys_conn, obj_path, NULL)) {
35 0 : return -EBUSY;
36 : }
37 :
38 57 : return 0;
39 : }
40 :
41 : /**
42 : * @brief Callback function for acquireing the bus name.
43 : * @remarks If the daemon is launched by systemd service,
44 : * it should notify to the systemd about its status when it is ready.
45 : */
46 : static void
47 19 : name_acquired_cb (GDBusConnection * connection,
48 : const gchar * name, gpointer user_data)
49 : {
50 19 : sd_notify (0, "READY=1");
51 19 : }
52 :
53 : /**
54 : * @brief Acquire the given name on the SYSTEM session of the DBus message bus.
55 : */
56 : int
57 20 : gdbus_get_name (const char *name)
58 : {
59 : guint id;
60 :
61 20 : id = g_bus_own_name_on_connection (g_dbus_sys_conn, name,
62 : G_BUS_NAME_OWNER_FLAGS_NONE, name_acquired_cb, NULL, NULL, NULL);
63 20 : if (id == 0)
64 1 : return -ENOSYS;
65 :
66 19 : return 0;
67 : }
68 :
69 : /**
70 : * @brief Connects the callback functions for each signal of the particular DBus interface.
71 : */
72 : int
73 57 : gdbus_connect_signal (gpointer instance, int num_signals,
74 : struct gdbus_signal_info *signal_infos)
75 : {
76 : int i;
77 : unsigned long handler_id;
78 :
79 399 : for (i = 0; i < num_signals; i++) {
80 342 : handler_id = g_signal_connect (instance,
81 : signal_infos[i].signal_name,
82 : signal_infos[i].cb, signal_infos[i].cb_data);
83 342 : if (handler_id <= 0)
84 0 : goto out_err;
85 342 : signal_infos[i].handler_id = handler_id;
86 : }
87 57 : return 0;
88 :
89 0 : out_err:
90 0 : for (i = 0; i < num_signals; i++) {
91 0 : if (signal_infos[i].handler_id > 0) {
92 0 : g_signal_handler_disconnect (instance, signal_infos[i].handler_id);
93 0 : signal_infos[i].handler_id = 0;
94 : }
95 : }
96 :
97 0 : return -EINVAL;
98 : }
99 :
100 : /**
101 : * @brief Disconnects the callback functions from the particular DBus interface.
102 : */
103 : void
104 57 : gdbus_disconnect_signal (gpointer instance, int num_signals,
105 : struct gdbus_signal_info *signal_infos)
106 : {
107 : int i;
108 :
109 399 : for (i = 0; i < num_signals; i++) {
110 342 : if (signal_infos[i].handler_id > 0) {
111 342 : g_signal_handler_disconnect (instance, signal_infos[i].handler_id);
112 342 : signal_infos[i].handler_id = 0;
113 : }
114 : }
115 57 : }
116 :
117 : /**
118 : * @brief Connect to the DBus message bus, which type is SYSTEM.
119 : */
120 : int
121 21 : gdbus_get_system_connection (gboolean is_session)
122 : {
123 21 : GError *err = NULL;
124 21 : GBusType bus_type = is_session ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM;
125 :
126 21 : g_clear_object (&g_dbus_sys_conn);
127 21 : g_dbus_sys_conn = g_bus_get_sync (bus_type, NULL, &err);
128 21 : if (g_dbus_sys_conn == NULL) {
129 2 : ml_loge ("Cannot connect to the system message bus: %s", err ? err->message : "Unknown error");
130 2 : g_clear_error (&err);
131 21 : return -ENOSYS;
132 : }
133 :
134 19 : return 0;
135 : }
136 :
137 : /**
138 : * @brief Disconnect the DBus message bus.
139 : */
140 : void
141 19 : gdbus_put_system_connection (void)
142 : {
143 19 : g_clear_object (&g_dbus_sys_conn);
144 19 : }
145 :
146 : /**
147 : * @brief Common function to initialize the DBus module.
148 : */
149 : void
150 57 : gdbus_initialize (void)
151 : {
152 57 : GError *err = NULL;
153 :
154 57 : if (!gst_init_check (NULL, NULL, &err))
155 0 : ml_loge ("Failed to initialize GStreamer: %s", (err ? err->message : "Unknown error"));
156 :
157 57 : g_clear_error (&err);
158 57 : }
|