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, g_strdup((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 GList *node = g_list_find_custom(*consumer_list, sender, (GCompareFunc) strcmp);
123 *consumer_list = g_list_delete_link(*consumer_list, node);
126 if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(watcher_id)) != NULL) {
127 g_bus_unwatch_name(watcher_id);
128 delete_monitoring_list(monitoring_hash, sender, watcher_id);
131 return STICKERD_SERVER_ERROR_NONE;
134 int stickerd_server_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable)
137 int own_id, registration_id;
138 GError *error = NULL;
139 GDBusNodeInfo *introspection_data = NULL;
141 if (_gdbus_connection == NULL) {
142 _gdbus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
143 if (_gdbus_connection == NULL) {
145 LOGE("g_bus_get_sync error message = %s", error->message);
148 result = STICKERD_SERVER_ERROR_IO_ERROR;
153 own_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
155 G_BUS_NAME_OWNER_FLAGS_NONE,
161 LOGE("Failed to register bus name");
162 result = STICKERD_SERVER_ERROR_IO_ERROR;
166 LOGD("own_id = %d", own_id);
168 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
169 if (introspection_data == NULL) {
170 LOGE("Failed to get GDBusNodeInfo");
171 result = STICKERD_SERVER_ERROR_IO_ERROR;
173 LOGE("g_dbus_node_info_new_for_xml error message = %s", error->message);
179 registration_id = g_dbus_connection_register_object(_gdbus_connection, STICKER_OBJECT_PATH,
180 introspection_data->interfaces[0], &interface_vtable, NULL, NULL, NULL);
181 LOGD("registration_id = %d", registration_id);
182 if (registration_id == 0) {
183 LOGE("Failed to register object");
184 result = STICKERD_SERVER_ERROR_IO_ERROR;
188 return STICKERD_SERVER_ERROR_NONE;
191 if (introspection_data)
192 g_dbus_node_info_unref(introspection_data);
197 int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, int watcher_id)
199 GList *monitoring_list = NULL;
200 GList *del_list = NULL;
203 monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(watcher_id));
204 if (monitoring_list == NULL) {
205 LOGE("The key(%d) is not found", watcher_id);
206 return STICKERD_SERVER_ERROR_IO_ERROR;
209 monitoring_list = g_list_first(monitoring_list);
210 del_list = g_list_find_custom(monitoring_list, sender, (GCompareFunc) strcmp);
213 LOGD("Delete sender(%s)", sender);
214 bus_name = g_list_nth_data(del_list, 0);
217 monitoring_list = g_list_delete_link(monitoring_list, del_list);
219 if (monitoring_list == NULL) {
220 g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(watcher_id));
222 monitoring_list = g_list_first(monitoring_list);
223 g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(watcher_id), monitoring_list);
226 return STICKERD_SERVER_ERROR_NONE;
229 int stickerd_send_dbus_message(GVariant *body, const char *dest, char *cmd, CLIENT_LIB lib)
232 char *interface = NULL;
234 if (lib == STICKER_CLIENT_LIB_PROVIDER)
235 interface = STICKER_PROVIDER_INTERFACE_NAME;
236 else if (lib == STICKER_CLIENT_LIB_CONSUMER)
237 interface = STICKER_CONSUMER_INTERFACE_NAME;
239 if (g_variant_is_floating(body))
242 if (!g_dbus_connection_emit_signal(_gdbus_connection,
250 LOGE("Failed to send dbus message : %s", err->message);
254 return STICKERD_SERVER_ERROR_IO_ERROR;
257 LOGD("Send message to client : %s", cmd);
258 return STICKERD_SERVER_ERROR_NONE;