tizen 2.3.1 release
[external/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., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, 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
30 GMainLoop *main_loop;
31
32 static gboolean async = FALSE;
33 static GOptionEntry entries[] =
34 {
35        { "async", 'a', 0, G_OPTION_ARG_NONE, &async,
36          "Asynchronously create intropection object", NULL },
37        { NULL }
38 };
39
40 static void
41 interrupt_signal_handler (int signum)
42 {
43         g_main_loop_quit (main_loop);
44 }
45
46 static void
47 print_action_arguments (GList *argument_list)
48 {
49         GList *iter;
50
51         g_print ("\targuments:\n");
52         for (iter = argument_list; iter; iter = iter->next) {
53                 GUPnPServiceActionArgInfo *argument;
54
55                 argument = (GUPnPServiceActionArgInfo *) iter->data;
56
57                 g_print ("\t\tname: %s\n"
58                          "\t\tdirection: %s\n"
59                          "\t\trelated state variable: %s\n\n",
60                          argument->name,
61                          (argument->direction ==
62                           GUPNP_SERVICE_ACTION_ARG_DIRECTION_IN)? "in": "out",
63                          argument->related_state_variable);
64         }
65 }
66
67 static void
68 print_actions (GUPnPServiceIntrospection *introspection)
69 {
70         const GList *action_list;
71
72         action_list = gupnp_service_introspection_list_actions (introspection);
73         if (action_list) {
74                 const GList *iter;
75
76                 g_print ("actions:\n");
77                 for (iter = action_list; iter; iter = iter->next) {
78                         GUPnPServiceActionInfo *action_info;
79
80                         action_info = (GUPnPServiceActionInfo *) iter->data;
81
82                         g_print ("\tname: %s\n", action_info->name);
83                         print_action_arguments (action_info->arguments);
84                 }
85                 g_print ("\n");
86         }
87 }
88
89 static void
90 print_state_variables (GUPnPServiceIntrospection *introspection)
91 {
92         const GList *variables;
93
94         variables =
95                 gupnp_service_introspection_list_state_variables (
96                                 introspection);
97         if (variables) {
98                 const GList *iter;
99
100                 g_print ("state variables:\n");
101                 for (iter = variables; iter; iter = iter->next) {
102                         GUPnPServiceStateVariableInfo *variable;
103                         GValue default_value;
104                         const char * default_value_str;
105
106                         variable = (GUPnPServiceStateVariableInfo *) iter->data;
107
108                         g_print ("\tname: %s\n"
109                                  "\ttype: %s\n"
110                                  "\tsend events: %s\n",
111                                  variable->name,
112                                  g_type_name (variable->type),
113                                  variable->send_events? "yes": "no");
114
115                         memset (&default_value, 0, sizeof (GValue));
116                         g_value_init (&default_value, G_TYPE_STRING);
117                         g_value_transform (&variable->default_value,
118                                            &default_value);
119                         default_value_str = g_value_get_string (&default_value);
120                         if (default_value_str) {
121                                 g_print ("\tdefault value: %s\n",
122                                          default_value_str);
123                         }
124                         g_value_unset (&default_value);
125
126                         if (variable->is_numeric) {
127                                 GValue min, max, step;
128
129                                 memset (&min, 0, sizeof (GValue));
130                                 memset (&max, 0, sizeof (GValue));
131                                 memset (&step, 0, sizeof (GValue));
132
133                                 g_value_init (&min, G_TYPE_STRING);
134                                 g_value_init (&max, G_TYPE_STRING);
135                                 g_value_init (&step, G_TYPE_STRING);
136
137                                 g_value_transform (&variable->minimum, &min);
138                                 g_value_transform (&variable->maximum, &max);
139                                 g_value_transform (&variable->step, &step);
140
141                                 g_print ("\tminimum: %s\n"
142                                          "\tmaximum: %s\n"
143                                          "\tstep: %s\n",
144                                          g_value_get_string (&min),
145                                          g_value_get_string (&max),
146                                          g_value_get_string (&step));
147
148                                 g_value_unset (&min);
149                                 g_value_unset (&max);
150                                 g_value_unset (&step);
151                         }
152
153                         if (variable->allowed_values) {
154                                 GList *value_iter;
155
156                                 g_print ("\tallowed values: ");
157                                 for (value_iter = variable->allowed_values;
158                                      value_iter;
159                                      value_iter = value_iter->next) {
160                                         g_print ("\"%s\" ",
161                                                  (gchar *) value_iter->data);
162                                 }
163                         }
164
165                         g_print ("\n");
166                 }
167                 g_print ("\n");
168         }
169 }
170
171 static void
172 got_introspection (GUPnPServiceInfo          *info,
173                    GUPnPServiceIntrospection *introspection,
174                    const GError              *error,
175                    gpointer                   user_data)
176 {
177         if (error) {
178                 g_warning ("Failed to create introspection for '%s': %s",
179                            gupnp_service_info_get_udn (info),
180                            error->message);
181
182                 return;
183         }
184
185         g_print ("service:  %s\nlocation: %s\n",
186                 gupnp_service_info_get_udn (info),
187                 gupnp_service_info_get_location (info));
188         print_actions (introspection);
189         print_state_variables (introspection);
190         g_object_unref (introspection);
191 }
192
193 static void
194 service_proxy_available_cb (GUPnPControlPoint *cp,
195                             GUPnPServiceProxy *proxy)
196 {
197         GUPnPServiceInfo *info;
198         GUPnPServiceIntrospection *introspection;
199         GError *error = NULL;
200
201         info = GUPNP_SERVICE_INFO (proxy);
202
203         if (async) {
204                 gupnp_service_info_get_introspection_async (info,
205                                                             got_introspection,
206                                                             NULL);
207         } else {
208                 introspection =
209                         gupnp_service_info_get_introspection (info, &error);
210                 got_introspection (info, introspection, error, NULL);
211
212                 if (error)
213                         g_error_free (error);
214         }
215 }
216
217 static void
218 service_proxy_unavailable_cb (GUPnPControlPoint *cp,
219                               GUPnPServiceProxy *proxy)
220 {
221         const char *type, *location;
222
223         type = gupnp_service_info_get_service_type (GUPNP_SERVICE_INFO (proxy));
224         location = gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy));
225
226         g_print ("Service unavailable:\n");
227         g_print ("\ttype:     %s\n", type);
228         g_print ("\tlocation: %s\n", location);
229 }
230
231 int
232 main (int argc, char **argv)
233 {
234         GError *error = NULL;
235         GUPnPContext *context;
236         GUPnPControlPoint *cp;
237         GOptionContext *option_context;
238         struct sigaction sig_action;
239
240         option_context = g_option_context_new ("- test GUPnP introspection");
241         g_option_context_add_main_entries (option_context,
242                                            entries,
243                                            NULL);
244         g_option_context_parse (option_context,
245                                 &argc,
246                                 &argv,
247                                 &error);
248         if (error) {
249                 g_printerr ("Error parsing the commandline arguments: %s\n",
250                             error->message);
251                 g_error_free (error);
252
253                 return EXIT_FAILURE;
254         }
255                 
256         g_thread_init (NULL);
257         g_type_init ();
258
259         error = NULL;
260         context = gupnp_context_new (NULL, NULL, 0, &error);
261         if (error) {
262                 g_printerr ("Error creating the GUPnP context: %s\n",
263                             error->message);
264                 g_error_free (error);
265
266                 return EXIT_FAILURE;
267         }
268
269         /* We're interested in everything */
270         cp = gupnp_control_point_new (context, "ssdp:all");
271
272         g_signal_connect (cp,
273                           "service-proxy-available",
274                           G_CALLBACK (service_proxy_available_cb),
275                           NULL);
276         g_signal_connect (cp,
277                           "service-proxy-unavailable",
278                           G_CALLBACK (service_proxy_unavailable_cb),
279                           NULL);
280
281         gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE);
282
283         main_loop = g_main_loop_new (NULL, FALSE);
284
285         /* Hook the handler for SIGTERM */
286         memset (&sig_action, 0, sizeof (sig_action));
287         sig_action.sa_handler = interrupt_signal_handler;
288         sigaction (SIGINT, &sig_action, NULL);
289
290         g_main_loop_run (main_loop);
291         g_main_loop_unref (main_loop);
292
293         g_object_unref (cp);
294         g_object_unref (context);
295
296         return EXIT_SUCCESS;
297 }