2 * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include "stickerd_dbus.h"
24 #include "stickerd_error.h"
29 #define LOG_TAG "STICKERD_DBUS"
31 static GDBusConnection *_gdbus_connection;
32 extern GMainLoop *main_loop;
34 int stickerd_server_register(GVariant *parameters, GVariant **reply_body, const gchar *sender, GBusNameAppearedCallback name_appeared_handler,
35 GBusNameVanishedCallback name_vanished_handler, GHashTable **monitoring_hash, GList **consumer_list)
37 int ret = STICKERD_SERVER_ERROR_NONE;
38 char *m_info_bus_name = NULL;
39 char *list_bus_name = NULL;
40 monitoring_info_s *m_info = NULL;
41 GList *monitoring_list = NULL;
44 g_variant_get(parameters, "(i)", &c_lib);
46 if (reply_body == NULL)
47 return STICKERD_SERVER_ERROR_INVALID_PARAMETER;
49 m_info_bus_name = strdup(sender);
50 list_bus_name = strdup(sender);
51 if (m_info_bus_name == NULL || list_bus_name == NULL) {
52 ret = STICKERD_SERVER_ERROR_IO_ERROR;
56 LOGD("Add a new sender");
57 m_info = (monitoring_info_s *)calloc(1, sizeof(monitoring_info_s));
59 LOGE("Failed to alloc memory");
60 ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
64 m_info->bus_name = m_info_bus_name;
65 m_info->watcher_id = g_bus_watch_name_on_connection(
68 G_BUS_NAME_WATCHER_FLAGS_NONE,
69 name_appeared_handler,
70 name_vanished_handler,
73 if (m_info->watcher_id == 0) {
74 LOGE("Failed to get identifier");
75 ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
79 *reply_body = g_variant_new("(i)", m_info->watcher_id);
80 if (*reply_body == NULL) {
81 LOGE("Failed to make reply");
82 ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
86 if ((CLIENT_LIB)c_lib == STICKER_CLIENT_LIB_CONSUMER)
87 *consumer_list = g_list_append(*consumer_list, strdup((const char *)sender));
89 LOGD("sender: %s, watcher: %d", sender, m_info->watcher_id);
90 monitoring_list = g_list_append(monitoring_list, list_bus_name);
91 if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(m_info->watcher_id)) == NULL)
92 g_hash_table_insert(*monitoring_hash, GUINT_TO_POINTER(m_info->watcher_id), monitoring_list);
94 LOGW("Sender(%s) already exist", sender);
96 return STICKERD_SERVER_ERROR_NONE;
100 free(m_info_bus_name);
113 int stickerd_server_unregister(GVariant *parameters, GVariant **reply_body, const gchar *sender, GHashTable **monitoring_hash, GList **consumer_list)
118 g_variant_get(parameters, "(ii)", &c_lib, &watcher_id);
120 if ((CLIENT_LIB)c_lib == STICKER_CLIENT_LIB_CONSUMER)
121 *consumer_list = g_list_remove(*consumer_list, sender);
123 if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(watcher_id)) != NULL) {
124 g_bus_unwatch_name(watcher_id);
125 delete_monitoring_list(monitoring_hash, sender, watcher_id);
128 return STICKERD_SERVER_ERROR_NONE;
131 int stickerd_server_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable)
134 int own_id, registration_id;
135 GError *error = NULL;
136 GDBusNodeInfo *introspection_data = NULL;
138 if (_gdbus_connection == NULL) {
139 _gdbus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
140 if (_gdbus_connection == NULL) {
142 LOGE("g_bus_get_sync error message = %s", error->message);
145 result = STICKERD_SERVER_ERROR_IO_ERROR;
150 own_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
152 G_BUS_NAME_OWNER_FLAGS_NONE,
158 LOGE("Failed to register bus name");
159 result = STICKERD_SERVER_ERROR_IO_ERROR;
163 LOGD("own_id = %d", own_id);
165 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
166 if (introspection_data == NULL) {
167 LOGE("Failed to get GDBusNodeInfo");
168 result = STICKERD_SERVER_ERROR_IO_ERROR;
170 LOGE("g_dbus_node_info_new_for_xml error message = %s", error->message);
176 registration_id = g_dbus_connection_register_object(_gdbus_connection, STICKER_OBJECT_PATH,
177 introspection_data->interfaces[0], &interface_vtable, NULL, NULL, NULL);
178 LOGD("registration_id = %d", registration_id);
179 if (registration_id == 0) {
180 LOGE("Failed to register object");
181 result = STICKERD_SERVER_ERROR_IO_ERROR;
185 return STICKERD_SERVER_ERROR_NONE;
188 if (introspection_data)
189 g_dbus_node_info_unref(introspection_data);
194 int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, int watcher_id)
196 GList *monitoring_list = NULL;
197 GList *del_list = NULL;
200 monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(watcher_id));
201 if (monitoring_list == NULL) {
202 LOGE("The key(%d) is not found", watcher_id);
203 return STICKERD_SERVER_ERROR_IO_ERROR;
206 monitoring_list = g_list_first(monitoring_list);
207 del_list = g_list_find_custom(monitoring_list, sender, (GCompareFunc) strcmp);
210 LOGD("Delete sender(%s)", sender);
211 bus_name = g_list_nth_data(del_list, 0);
214 monitoring_list = g_list_delete_link(monitoring_list, del_list);
216 if (monitoring_list == NULL) {
217 g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(watcher_id));
219 monitoring_list = g_list_first(monitoring_list);
220 g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(watcher_id), monitoring_list);
223 return STICKERD_SERVER_ERROR_NONE;
226 int stickerd_send_dbus_message(GVariant *body, const char *dest, char *cmd, CLIENT_LIB lib)
229 char *interface = NULL;
231 if (lib == STICKER_CLIENT_LIB_PROVIDER)
232 interface = STICKER_PROVIDER_INTERFACE_NAME;
233 else if (lib == STICKER_CLIENT_LIB_CONSUMER)
234 interface = STICKER_CONSUMER_INTERFACE_NAME;
236 if (g_variant_is_floating(body))
239 if (!g_dbus_connection_emit_signal(_gdbus_connection,
247 LOGE("Failed to send dbus message : %s", err->message);
251 return STICKERD_SERVER_ERROR_IO_ERROR;
254 LOGD("Send message to client : %s", cmd);
255 return STICKERD_SERVER_ERROR_NONE;