Update to v0.4.0
[profile/ivi/dLeyna.git] / dleyna-server / libdleyna / server / manager.c
1 /*
2  * dLeyna
3  *
4  * Copyright (C) 2013 Intel Corporation. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU Lesser General Public License,
8  * version 2.1, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
13  * for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Ludovic Ferrandis <ludovic.ferrandis@intel.com>
20  *
21  */
22
23 #include <glib.h>
24 #include <string.h>
25
26 #include <libdleyna/core/error.h>
27 #include <libdleyna/core/log.h>
28 #include <libdleyna/core/service-task.h>
29 #include <libdleyna/core/white-list.h>
30
31 #include "interface.h"
32 #include "manager.h"
33 #include "props.h"
34
35 struct dls_manager_t_ {
36         dleyna_connector_id_t connection;
37         GUPnPContextManager *cm;
38         dleyna_white_list_t *wl;
39 };
40
41 static void prv_wl_notify_prop(dls_manager_t *manager,
42                                const gchar *prop_name,
43                                GVariant *prop_val)
44 {
45         GVariant *val;
46         GVariantBuilder array;
47
48         g_variant_builder_init(&array, G_VARIANT_TYPE("a{sv}"));
49         g_variant_builder_add(&array, "{sv}", prop_name, prop_val);
50
51         val = g_variant_new("(s@a{sv}as)", DLEYNA_SERVER_INTERFACE_MANAGER,
52                             g_variant_builder_end(&array),
53                             NULL);
54
55         (void) dls_server_get_connector()->notify(manager->connection,
56                                            DLEYNA_SERVER_OBJECT,
57                                            DLS_INTERFACE_PROPERTIES,
58                                            DLS_INTERFACE_PROPERTIES_CHANGED,
59                                            val,
60                                            NULL);
61 }
62
63 dls_manager_t *dls_manager_new(dleyna_connector_id_t connection,
64                                GUPnPContextManager *connection_manager)
65 {
66         dls_manager_t *manager = g_new0(dls_manager_t, 1);
67         GUPnPWhiteList *gupnp_wl;
68
69         gupnp_wl = gupnp_context_manager_get_white_list(connection_manager);
70
71         manager->connection = connection;
72         manager->cm = connection_manager;
73         manager->wl = dleyna_white_list_new(gupnp_wl);
74
75         return manager;
76 }
77
78 void dls_manager_delete(dls_manager_t *manager)
79 {
80         if (manager != NULL) {
81                 dleyna_white_list_delete(manager->wl);
82                 g_free(manager);
83         }
84 }
85
86 dleyna_white_list_t *dls_manager_get_white_list(dls_manager_t *manager)
87 {
88         return manager->wl;
89 }
90
91 void dls_manager_get_all_props(dls_manager_t *manager,
92                                dleyna_settings_t *settings,
93                                dls_task_t *task,
94                                dls_manager_task_complete_t cb)
95 {
96         dls_async_task_t *cb_data = (dls_async_task_t *)task;
97         dls_async_get_all_t *cb_task_data;
98         dls_task_get_props_t *task_data = &task->ut.get_props;
99         gchar *i_name = task_data->interface_name;
100
101         DLEYNA_LOG_DEBUG("Enter");
102         DLEYNA_LOG_DEBUG("Path: %s", task->target.path);
103         DLEYNA_LOG_DEBUG("Interface %s", i_name);
104
105         cb_data->cb = cb;
106
107         cb_task_data = &cb_data->ut.get_all;
108         cb_task_data->vb = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
109
110         if (!strcmp(i_name, DLEYNA_SERVER_INTERFACE_MANAGER) ||
111             !strcmp(i_name, "")) {
112                 dls_props_add_manager(settings, cb_task_data->vb);
113
114                 cb_data->task.result = g_variant_ref_sink(
115                                                 g_variant_builder_end(
116                                                         cb_task_data->vb));
117         } else {
118                 DLEYNA_LOG_WARNING("Interface is unknown.");
119
120                 cb_data->error = g_error_new(DLEYNA_SERVER_ERROR,
121                                              DLEYNA_ERROR_UNKNOWN_INTERFACE,
122                                              "Interface is unknown.");
123         }
124
125         (void) g_idle_add(dls_async_task_complete, cb_data);
126
127         DLEYNA_LOG_DEBUG("Exit");
128 }
129
130 void dls_manager_get_prop(dls_manager_t *manager,
131                           dleyna_settings_t *settings,
132                           dls_task_t *task,
133                           dls_manager_task_complete_t cb)
134 {
135         dls_async_task_t *cb_data = (dls_async_task_t *)task;
136         dls_task_get_prop_t *task_data = &task->ut.get_prop;
137         gchar *i_name = task_data->interface_name;
138         gchar *name = task_data->prop_name;
139
140         DLEYNA_LOG_DEBUG("Enter");
141         DLEYNA_LOG_DEBUG("Path: %s", task->target.path);
142         DLEYNA_LOG_DEBUG("Interface %s", i_name);
143         DLEYNA_LOG_DEBUG("Prop.%s", name);
144
145         cb_data->cb = cb;
146
147         if (!strcmp(i_name, DLEYNA_SERVER_INTERFACE_MANAGER) ||
148             !strcmp(i_name, "")) {
149                 cb_data->task.result = dls_props_get_manager_prop(settings,
150                                                                   name);
151
152                 if (!cb_data->task.result)
153                         cb_data->error = g_error_new(
154                                                 DLEYNA_SERVER_ERROR,
155                                                 DLEYNA_ERROR_UNKNOWN_PROPERTY,
156                                                 "Unknown property");
157         } else {
158                 DLEYNA_LOG_WARNING("Interface is unknown.");
159
160                 cb_data->error = g_error_new(DLEYNA_SERVER_ERROR,
161                                              DLEYNA_ERROR_UNKNOWN_INTERFACE,
162                                              "Interface is unknown.");
163         }
164
165         (void) g_idle_add(dls_async_task_complete, cb_data);
166
167         DLEYNA_LOG_DEBUG("Exit");
168 }
169
170 static void prv_set_prop_never_quit(dls_manager_t *manager,
171                                     dleyna_settings_t *settings,
172                                     gboolean never_quit,
173                                     GError **error)
174 {
175         GVariant *prop_val;
176         gboolean old_val;
177
178         DLEYNA_LOG_DEBUG("Enter %d", never_quit);
179
180         old_val = dleyna_settings_is_never_quit(settings);
181
182         if (old_val == never_quit)
183                 goto exit;
184
185         /* If no error, the white list will be updated in the reload callack
186          */
187         dleyna_settings_set_never_quit(settings, never_quit, error);
188
189         if (*error == NULL) {
190                 prop_val = g_variant_new_boolean(never_quit);
191                 prv_wl_notify_prop(manager,
192                                    DLS_INTERFACE_PROP_NEVER_QUIT,
193                                    prop_val);
194         }
195
196 exit:
197         DLEYNA_LOG_DEBUG("Exit");
198         return;
199 }
200
201 static void prv_set_prop_wl_enabled(dls_manager_t *manager,
202                                      dleyna_settings_t *settings,
203                                      gboolean enabled,
204                                      GError **error)
205 {
206         GVariant *prop_val;
207         gboolean old_val;
208
209         DLEYNA_LOG_DEBUG("Enter %d", enabled);
210
211         old_val = dleyna_settings_is_white_list_enabled(settings);
212
213         if (old_val == enabled)
214                 goto exit;
215
216         /* If no error, the white list will be updated in the reload callack
217          */
218         dleyna_settings_set_white_list_enabled(settings, enabled, error);
219
220         if (*error == NULL) {
221                 dleyna_white_list_enable(manager->wl, enabled);
222
223                 prop_val = g_variant_new_boolean(enabled);
224                 prv_wl_notify_prop(manager,
225                                    DLS_INTERFACE_PROP_WHITE_LIST_ENABLED,
226                                    prop_val);
227         }
228
229 exit:
230         DLEYNA_LOG_DEBUG("Exit");
231         return;
232 }
233
234 static void prv_set_prop_wl_entries(dls_manager_t *manager,
235                                      dleyna_settings_t *settings,
236                                      GVariant *entries,
237                                      GError **error)
238 {
239         DLEYNA_LOG_DEBUG("Enter");
240
241         if (strcmp(g_variant_get_type_string(entries), "as")) {
242                 DLEYNA_LOG_WARNING("Invalid parameter type. 'as' expected.");
243
244                 *error = g_error_new(DLEYNA_SERVER_ERROR,
245                                      DLEYNA_ERROR_BAD_QUERY,
246                                      "Invalid parameter type. 'as' expected.");
247                 goto exit;
248         }
249
250         /* If no error, the white list will be updated in the reload callack
251          * callack
252          */
253         dleyna_settings_set_white_list_entries(settings, entries, error);
254
255         if (*error == NULL) {
256                 dleyna_white_list_clear(manager->wl);
257                 dleyna_white_list_add_entries(manager->wl, entries);
258
259                 prv_wl_notify_prop(manager,
260                                    DLS_INTERFACE_PROP_WHITE_LIST_ENTRIES,
261                                    entries);
262         }
263
264 exit:
265         DLEYNA_LOG_DEBUG("Exit");
266 }
267
268 void dls_manager_set_prop(dls_manager_t *manager,
269                           dleyna_settings_t *settings,
270                           dls_task_t *task,
271                           dls_manager_task_complete_t cb)
272 {
273         dls_async_task_t *cb_data = (dls_async_task_t *)task;
274         dls_task_set_prop_t *task_data = &task->ut.set_prop;
275         GVariant *param = task_data->params;
276         gchar *name = task_data->prop_name;
277         gchar *i_name = task_data->interface_name;
278         GError *error = NULL;
279
280         DLEYNA_LOG_DEBUG("Enter");
281         DLEYNA_LOG_DEBUG("Path: %s", task->target.path);
282         DLEYNA_LOG_DEBUG("Interface %s", i_name);
283         DLEYNA_LOG_DEBUG("Prop.%s", name);
284
285         cb_data->cb = cb;
286
287         if (strcmp(i_name, DLEYNA_SERVER_INTERFACE_MANAGER) &&
288             strcmp(i_name, "")) {
289                 DLEYNA_LOG_WARNING("Interface is unknown.");
290
291                 cb_data->error = g_error_new(DLEYNA_SERVER_ERROR,
292                                              DLEYNA_ERROR_UNKNOWN_INTERFACE,
293                                              "Interface is unknown.");
294                 goto exit;
295         }
296
297         if (!strcmp(name, DLS_INTERFACE_PROP_NEVER_QUIT))
298                 prv_set_prop_never_quit(manager, settings,
299                                         g_variant_get_boolean(param),
300                                         &error);
301         else if (!strcmp(name, DLS_INTERFACE_PROP_WHITE_LIST_ENABLED))
302                 prv_set_prop_wl_enabled(manager, settings,
303                                         g_variant_get_boolean(param),
304                                         &error);
305         else if (!strcmp(name, DLS_INTERFACE_PROP_WHITE_LIST_ENTRIES))
306                 prv_set_prop_wl_entries(manager, settings, param, &error);
307         else
308                 cb_data->error = g_error_new(DLEYNA_SERVER_ERROR,
309                                              DLEYNA_ERROR_UNKNOWN_PROPERTY,
310                                              "Unknown property");
311
312         if (error != NULL)
313                 cb_data->error = error;
314
315 exit:
316         (void) g_idle_add(dls_async_task_complete, cb_data);
317         DLEYNA_LOG_DEBUG("Exit");
318 }