Update gupnp to 0.20.3 (161969f)
[profile/ivi/GUPnP.git] / tests / test-introspection.c
1 /*
2  * Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
3  * Copyright (C) 2007 OpenedHand Ltd.
4  *
5  * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
6  *         Jorn Baayen <jorn@openedhand.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include <libgupnp/gupnp-control-point.h>
25 #include <libgupnp/gupnp-service-introspection.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <signal.h>
29 #include <glib.h>
30
31 GMainLoop *main_loop;
32
33 static gboolean async = FALSE;
34 static GOptionEntry entries[] =
35 {
36        { "async", 'a', 0, G_OPTION_ARG_NONE, &async,
37          "Asynchronously create intropection object", NULL },
38        { NULL }
39 };
40
41 static void
42 interrupt_signal_handler (G_GNUC_UNUSED int signum)
43 {
44         g_main_loop_quit (main_loop);
45 }
46
47 static void
48 print_action_arguments (GList *argument_list)
49 {
50         GList *iter;
51
52         g_print ("\targuments:\n");
53         for (iter = argument_list; iter; iter = iter->next) {
54                 GUPnPServiceActionArgInfo *argument;
55
56                 argument = (GUPnPServiceActionArgInfo *) iter->data;
57
58                 g_print ("\t\tname: %s\n"
59                          "\t\tdirection: %s\n"
60                          "\t\trelated state variable: %s\n\n",
61                          argument->name,
62                          (argument->direction ==
63                           GUPNP_SERVICE_ACTION_ARG_DIRECTION_IN)? "in": "out",
64                          argument->related_state_variable);
65         }
66 }
67
68 static void
69 print_actions (GUPnPServiceIntrospection *introspection)
70 {
71         const GList *action_list;
72
73         action_list = gupnp_service_introspection_list_actions (introspection);
74         if (action_list) {
75                 const GList *iter;
76
77                 g_print ("actions:\n");
78                 for (iter = action_list; iter; iter = iter->next) {
79                         GUPnPServiceActionInfo *action_info;
80
81                         action_info = (GUPnPServiceActionInfo *) iter->data;
82
83                         g_print ("\tname: %s\n", action_info->name);
84                         print_action_arguments (action_info->arguments);
85                 }
86                 g_print ("\n");
87         }
88 }
89
90 static void
91 print_state_variables (GUPnPServiceIntrospection *introspection)
92 {
93         const GList *variables;
94
95         variables =
96                 gupnp_service_introspection_list_state_variables (
97                                 introspection);
98         if (variables) {
99                 const GList *iter;
100
101                 g_print ("state variables:\n");
102                 for (iter = variables; iter; iter = iter->next) {
103                         GUPnPServiceStateVariableInfo *variable;
104                         GValue default_value;
105                         const char * default_value_str;
106
107                         variable = (GUPnPServiceStateVariableInfo *) iter->data;
108
109                         g_print ("\tname: %s\n"
110                                  "\ttype: %s\n"
111                                  "\tsend events: %s\n",
112                                  variable->name,
113                                  g_type_name (variable->type),
114                                  variable->send_events? "yes": "no");
115
116                         memset (&default_value, 0, sizeof (GValue));
117                         g_value_init (&default_value, G_TYPE_STRING);
118                         g_value_transform (&variable->default_value,
119                                            &default_value);
120                         default_value_str = g_value_get_string (&default_value);
121                         if (default_value_str) {
122                                 g_print ("\tdefault value: %s\n",
123                                          default_value_str);
124                         }
125                         g_value_unset (&default_value);
126
127                         if (variable->is_numeric) {
128                                 GValue min, max, step;
129
130                                 memset (&min, 0, sizeof (GValue));
131                                 memset (&max, 0, sizeof (GValue));
132                                 memset (&step, 0, sizeof (GValue));
133
134                                 g_value_init (&min, G_TYPE_STRING);
135                                 g_value_init (&max, G_TYPE_STRING);
136                                 g_value_init (&step, G_TYPE_STRING);
137
138                                 g_value_transform (&variable->minimum, &min);
139                                 g_value_transform (&variable->maximum, &max);
140                                 g_value_transform (&variable->step, &step);
141
142                                 g_print ("\tminimum: %s\n"
143                                          "\tmaximum: %s\n"
144                                          "\tstep: %s\n",
145                                          g_value_get_string (&min),
146                                          g_value_get_string (&max),
147                                          g_value_get_string (&step));
148
149                                 g_value_unset (&min);
150                                 g_value_unset (&max);
151                                 g_value_unset (&step);
152                         }
153
154                         if (variable->allowed_values) {
155                                 GList *value_iter;
156
157                                 g_print ("\tallowed values: ");
158                                 for (value_iter = variable->allowed_values;
159                                      value_iter;
160                                      value_iter = value_iter->next) {
161                                         g_print ("\"%s\" ",
162                                                  (gchar *) value_iter->data);
163                                 }
164                         }
165
166                         g_print ("\n");
167                 }
168                 g_print ("\n");
169         }
170 }
171
172 static void
173 got_introspection (GUPnPServiceInfo          *info,
174                    GUPnPServiceIntrospection *introspection,
175                    const GError              *error,
176                    G_GNUC_UNUSED gpointer     user_data)
177 {
178         if (error) {
179                 g_warning ("Failed to create introspection for '%s': %s",
180                            gupnp_service_info_get_udn (info),
181                            error->message);
182
183                 return;
184         }
185
186         g_print ("service:  %s\nlocation: %s\n",
187                 gupnp_service_info_get_udn (info),
188                 gupnp_service_info_get_location (info));
189         print_actions (introspection);
190         print_state_variables (introspection);
191         g_object_unref (introspection);
192 }
193
194 static void
195 service_proxy_available_cb (G_GNUC_UNUSED GUPnPControlPoint *cp,
196                             GUPnPServiceProxy               *proxy)
197 {
198         GUPnPServiceInfo *info;
199         GUPnPServiceIntrospection *introspection;
200         GError *error = NULL;
201
202         info = GUPNP_SERVICE_INFO (proxy);
203
204         if (async) {
205                 gupnp_service_info_get_introspection_async (info,
206                                                             got_introspection,
207                                                             NULL);
208         } else {
209                 introspection =
210                         gupnp_service_info_get_introspection (info, &error);
211                 got_introspection (info, introspection, error, NULL);
212
213                 if (error)
214                         g_error_free (error);
215         }
216 }
217
218 static void
219 service_proxy_unavailable_cb (G_GNUC_UNUSED GUPnPControlPoint *cp,
220                               GUPnPServiceProxy               *proxy)
221 {
222         const char *type, *location;
223
224         type = gupnp_service_info_get_service_type (GUPNP_SERVICE_INFO (proxy));
225         location = gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy));
226
227         g_print ("Service unavailable:\n");
228         g_print ("\ttype:     %s\n", type);
229         g_print ("\tlocation: %s\n", location);
230 }
231
232 int
233 main (int argc, char **argv)
234 {
235         GError *error = NULL;
236         GUPnPContext *context;
237         GUPnPControlPoint *cp;
238         GOptionContext *option_context;
239 #ifndef G_OS_WIN32
240         struct sigaction sig_action;
241 #endif /* G_OS_WIN32 */
242
243         option_context = g_option_context_new ("- test GUPnP introspection");
244         g_option_context_add_main_entries (option_context,
245                                            entries,
246                                            NULL);
247         g_option_context_parse (option_context,
248                                 &argc,
249                                 &argv,
250                                 &error);
251         if (error) {
252                 g_printerr ("Error parsing the commandline arguments: %s\n",
253                             error->message);
254                 g_error_free (error);
255
256                 return EXIT_FAILURE;
257         }
258                 
259 #if !GLIB_CHECK_VERSION(2,35,0)
260         g_type_init ();
261 #endif
262
263         error = NULL;
264         context = g_initable_new (GUPNP_TYPE_CONTEXT, NULL, &error, NULL);
265         if (error) {
266                 g_printerr ("Error creating the GUPnP context: %s\n",
267                             error->message);
268                 g_error_free (error);
269
270                 return EXIT_FAILURE;
271         }
272
273         /* We're interested in everything */
274         cp = gupnp_control_point_new (context, "ssdp:all");
275
276         g_signal_connect (cp,
277                           "service-proxy-available",
278                           G_CALLBACK (service_proxy_available_cb),
279                           NULL);
280         g_signal_connect (cp,
281                           "service-proxy-unavailable",
282                           G_CALLBACK (service_proxy_unavailable_cb),
283                           NULL);
284
285         gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE);
286
287         main_loop = g_main_loop_new (NULL, FALSE);
288
289         /* Hook the handler for SIGTERM */
290 #ifndef G_OS_WIN32
291         memset (&sig_action, 0, sizeof (sig_action));
292         sig_action.sa_handler = interrupt_signal_handler;
293         sigaction (SIGINT, &sig_action, NULL);
294 #else
295         signal(SIGINT,interrupt_signal_handler);
296 #endif /* G_OS_WIN32 */
297
298         g_main_loop_run (main_loop);
299         g_main_loop_unref (main_loop);
300
301         g_object_unref (cp);
302         g_object_unref (context);
303
304         return EXIT_SUCCESS;
305 }