diff options
author | Jens Georg <mail@jensge.org> | 2021-05-30 12:00:42 +0200 |
---|---|---|
committer | Jens Georg <mail@jensge.org> | 2021-06-09 23:55:54 +0200 |
commit | f26b70a719272e85dcc6fdc1a0afc276ae5e106e (patch) | |
tree | 651418dd3903e519da28a69f5349e86552bd4cf3 /examples | |
parent | 433d1c1cb9fb4773a3ccda412b782d8b70c372b6 (diff) | |
download | gupnp-f26b70a719272e85dcc6fdc1a0afc276ae5e106e.tar.gz |
tests,examples: Some tests are examples
Those are moved into examples, and gtests is moved one up
Diffstat (limited to 'examples')
-rw-r--r-- | examples/meson.build | 9 | ||||
-rw-r--r-- | examples/test-browsing.c | 168 | ||||
-rw-r--r-- | examples/test-introspection.c | 286 | ||||
-rw-r--r-- | examples/test-proxy.c | 232 | ||||
-rw-r--r-- | examples/test-server.c | 164 | ||||
-rw-r--r-- | examples/test-white-list.c | 301 |
6 files changed, 1160 insertions, 0 deletions
diff --git a/examples/meson.build b/examples/meson.build index c8d0d3c..eb32dfd 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -16,3 +16,12 @@ executable( 'get-volume.c', dependencies: gupnp ) + +foreach program : ['browsing', 'proxy', 'server', 'introspection', 'white-list'] + executable( + 'test-' + program, + sources : 'test-@0@.c'.format(program), + dependencies : [gupnp, gio_unix] + ) +endforeach + diff --git a/examples/test-browsing.c b/examples/test-browsing.c new file mode 100644 index 0000000..1dd4560 --- /dev/null +++ b/examples/test-browsing.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2007 OpenedHand Ltd. + * + * Author: Jorn Baayen <jorn@openedhand.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <libgupnp/gupnp-control-point.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> +#include <signal.h> +#include <glib.h> + +GMainLoop *main_loop; + +#ifndef G_OS_WIN32 +#include <glib-unix.h> +#endif + +static gboolean +unix_signal_handler (gpointer user_data) +{ + g_main_loop_quit (main_loop); + + return G_SOURCE_REMOVE; +} + + +#ifdef G_OS_WIN32 +/* + * Since in Windows this is basically called from + * the ConsoleCtrlHandler which does not share the restrictions of Unix signals + */ +static void +interrupt_signal_handler (G_GNUC_UNUSED int signum) +{ + unix_signal_handler (NULL); +} + +#endif +static void +device_proxy_available_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPDeviceProxy *proxy) +{ + const char *type, *location; + + type = gupnp_device_info_get_device_type (GUPNP_DEVICE_INFO (proxy)); + location = gupnp_device_info_get_location (GUPNP_DEVICE_INFO (proxy)); + + g_print ("Device available:\n"); + g_print ("\ttype: %s\n", type); + g_print ("\tlocation: %s\n", location); +} + +static void +device_proxy_unavailable_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPDeviceProxy *proxy) +{ + const char *type, *location; + + type = gupnp_device_info_get_device_type (GUPNP_DEVICE_INFO (proxy)); + location = gupnp_device_info_get_location (GUPNP_DEVICE_INFO (proxy)); + + g_print ("Device unavailable:\n"); + g_print ("\ttype: %s\n", type); + g_print ("\tlocation: %s\n", location); +} + +static void +service_proxy_available_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPServiceProxy *proxy) +{ + const char *type, *location; + + type = gupnp_service_info_get_service_type (GUPNP_SERVICE_INFO (proxy)); + location = gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy)); + + g_print ("Service available:\n"); + g_print ("\ttype: %s\n", type); + g_print ("\tlocation: %s\n", location); +} + +static void +service_proxy_unavailable_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPServiceProxy *proxy) +{ + const char *type, *location; + + type = gupnp_service_info_get_service_type (GUPNP_SERVICE_INFO (proxy)); + location = gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy)); + + g_print ("Service unavailable:\n"); + g_print ("\ttype: %s\n", type); + g_print ("\tlocation: %s\n", location); +} + +int +main (G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) +{ + GError *error; + GUPnPContext *context; + GUPnPControlPoint *cp; + + setlocale (LC_ALL, ""); + + error = NULL; + context = g_initable_new (GUPNP_TYPE_CONTEXT, NULL, &error, NULL); + if (error) { + g_printerr ("Error creating the GUPnP context: %s\n", + error->message); + g_error_free (error); + + return EXIT_FAILURE; + } + + /* We're interested in everything */ + cp = gupnp_control_point_new (context, "ssdp:all"); + + g_signal_connect (cp, + "device-proxy-available", + G_CALLBACK (device_proxy_available_cb), + NULL); + g_signal_connect (cp, + "device-proxy-unavailable", + G_CALLBACK (device_proxy_unavailable_cb), + NULL); + g_signal_connect (cp, + "service-proxy-available", + G_CALLBACK (service_proxy_available_cb), + NULL); + g_signal_connect (cp, + "service-proxy-unavailable", + G_CALLBACK (service_proxy_unavailable_cb), + NULL); + + gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE); + + main_loop = g_main_loop_new (NULL, FALSE); + +#ifndef G_OS_WIN32 + g_unix_signal_add (SIGINT, unix_signal_handler, NULL); +#else + signal(SIGINT, interrupt_signal_handler); +#endif /* G_OS_WIN32 */ + + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + g_object_unref (cp); + g_object_unref (context); + + return EXIT_SUCCESS; +} diff --git a/examples/test-introspection.c b/examples/test-introspection.c new file mode 100644 index 0000000..1512317 --- /dev/null +++ b/examples/test-introspection.c @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * Copyright (C) 2007 OpenedHand Ltd. + * + * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * Jorn Baayen <jorn@openedhand.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <libgupnp/gupnp-control-point.h> +#include <libgupnp/gupnp-service-introspection.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <glib.h> + +#ifndef G_OS_WIN32 +#include <glib-unix.h> +#endif + +GMainLoop *main_loop; + +static GCancellable *cancellable; + +static gboolean +unix_signal_handler (gpointer user_data) +{ + if (g_cancellable_is_cancelled (cancellable)) { + g_main_loop_quit (main_loop); + + return G_SOURCE_REMOVE; + } else { + g_print ("Canceling all introspection calls. " + "Press ^C again to force quit.\n"); + g_cancellable_cancel (cancellable); + return G_SOURCE_CONTINUE; + } +} + +#ifdef G_OS_WIN32 +/* + * Since in Windows this is basically called from + * the ConsoleCtrlHandler which does not share the restrictions of Unix signals + */ +static void +interrupt_signal_handler (G_GNUC_UNUSED int signum) +{ + unix_signal_handler (NULL); +} + +#endif + +static void +print_action_arguments (GList *argument_list) +{ + GList *iter; + + g_print ("\targuments:\n"); + for (iter = argument_list; iter; iter = iter->next) { + GUPnPServiceActionArgInfo *argument; + + argument = (GUPnPServiceActionArgInfo *) iter->data; + + g_print ("\t\tname: %s\n" + "\t\tdirection: %s\n" + "\t\trelated state variable: %s\n\n", + argument->name, + (argument->direction == + GUPNP_SERVICE_ACTION_ARG_DIRECTION_IN)? "in": "out", + argument->related_state_variable); + } +} + +static void +print_actions (GUPnPServiceIntrospection *introspection) +{ + const GList *action_list; + + action_list = gupnp_service_introspection_list_actions (introspection); + if (action_list) { + const GList *iter; + + g_print ("actions:\n"); + for (iter = action_list; iter; iter = iter->next) { + GUPnPServiceActionInfo *action_info; + + action_info = (GUPnPServiceActionInfo *) iter->data; + + g_print ("\tname: %s\n", action_info->name); + print_action_arguments (action_info->arguments); + } + g_print ("\n"); + } +} + +static void +print_state_variables (GUPnPServiceIntrospection *introspection) +{ + const GList *variables; + + variables = + gupnp_service_introspection_list_state_variables ( + introspection); + if (variables) { + const GList *iter; + + g_print ("state variables:\n"); + for (iter = variables; iter; iter = iter->next) { + GUPnPServiceStateVariableInfo *variable; + GValue default_value = G_VALUE_INIT; + const char * default_value_str; + + variable = (GUPnPServiceStateVariableInfo *) iter->data; + + g_print ("\tname: %s\n" + "\ttype: %s\n" + "\tsend events: %s\n", + variable->name, + g_type_name (variable->type), + variable->send_events? "yes": "no"); + + g_value_init (&default_value, G_TYPE_STRING); + g_value_transform (&variable->default_value, + &default_value); + default_value_str = g_value_get_string (&default_value); + if (default_value_str) { + g_print ("\tdefault value: %s\n", + default_value_str); + } + g_value_unset (&default_value); + + if (variable->is_numeric) { + GValue min = G_VALUE_INIT, max = G_VALUE_INIT, step = G_VALUE_INIT; + + g_value_init (&min, G_TYPE_STRING); + g_value_init (&max, G_TYPE_STRING); + g_value_init (&step, G_TYPE_STRING); + + g_value_transform (&variable->minimum, &min); + g_value_transform (&variable->maximum, &max); + g_value_transform (&variable->step, &step); + + g_print ("\tminimum: %s\n" + "\tmaximum: %s\n" + "\tstep: %s\n", + g_value_get_string (&min), + g_value_get_string (&max), + g_value_get_string (&step)); + + g_value_unset (&min); + g_value_unset (&max); + g_value_unset (&step); + } + + if (variable->allowed_values) { + GList *value_iter; + + g_print ("\tallowed values: "); + for (value_iter = variable->allowed_values; + value_iter; + value_iter = value_iter->next) { + g_print ("\"%s\" ", + (gchar *) value_iter->data); + } + } + + g_print ("\n"); + } + g_print ("\n"); + } +} + +static void +got_introspection (GUPnPServiceInfo *info, + GUPnPServiceIntrospection *introspection, + const GError *error, + G_GNUC_UNUSED gpointer user_data) +{ + if (error) { + g_warning ("Failed to create introspection for '%s': %s", + gupnp_service_info_get_udn (info), + error->message); + + return; + } + + g_print ("service: %s\nlocation: %s\n", + gupnp_service_info_get_udn (info), + gupnp_service_info_get_location (info)); + print_actions (introspection); + print_state_variables (introspection); + g_object_unref (introspection); +} + +static void +service_proxy_available_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPServiceProxy *proxy) +{ + GUPnPServiceInfo *info; + + info = GUPNP_SERVICE_INFO (proxy); + + gupnp_service_info_get_introspection_async_full (info, + got_introspection, + cancellable, + NULL); +} + +static void +service_proxy_unavailable_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPServiceProxy *proxy) +{ + const char *type, *location; + + type = gupnp_service_info_get_service_type (GUPNP_SERVICE_INFO (proxy)); + location = gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy)); + + g_print ("Service unavailable:\n"); + g_print ("\ttype: %s\n", type); + g_print ("\tlocation: %s\n", location); +} + +int +main (int argc, char **argv) +{ + GError *error = NULL; + GUPnPContext *context; + GUPnPControlPoint *cp; + + error = NULL; + context = g_initable_new (GUPNP_TYPE_CONTEXT, NULL, &error, NULL); + if (error) { + g_printerr ("Error creating the GUPnP context: %s\n", + error->message); + g_error_free (error); + + return EXIT_FAILURE; + } + + cancellable = g_cancellable_new (); + + /* We're interested in everything */ + cp = gupnp_control_point_new (context, "ssdp:all"); + + g_signal_connect (cp, + "service-proxy-available", + G_CALLBACK (service_proxy_available_cb), + NULL); + g_signal_connect (cp, + "service-proxy-unavailable", + G_CALLBACK (service_proxy_unavailable_cb), + NULL); + + gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE); + + main_loop = g_main_loop_new (NULL, FALSE); + + /* Hook the handler for SIGINT */ +#ifndef G_OS_WIN32 + g_unix_signal_add (SIGINT, unix_signal_handler, NULL); +#else + signal(SIGINT,interrupt_signal_handler); +#endif /* G_OS_WIN32 */ + + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + g_object_unref (cp); + g_object_unref (context); + + return EXIT_SUCCESS; +} diff --git a/examples/test-proxy.c b/examples/test-proxy.c new file mode 100644 index 0000000..bbf44d6 --- /dev/null +++ b/examples/test-proxy.c @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2007 OpenedHand Ltd. + * + * Author: Jorn Baayen <jorn@openedhand.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <libgupnp/gupnp-control-point.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> +#include <signal.h> +#include <glib.h> + +GMainLoop *main_loop; + +#ifndef G_OS_WIN32 +#include <glib-unix.h> +#endif + +static gboolean +unix_signal_handler (gpointer user_data) +{ + g_main_loop_quit (main_loop); + + return G_SOURCE_REMOVE; +} + +#ifdef G_OS_WIN32 +/* + * Since in Windows this is basically called from + * the ConsoleCtrlHandler which does not share the restrictions of Unix signals + */ +static void +interrupt_signal_handler (G_GNUC_UNUSED int signum) +{ + unix_signal_handler (NULL); +} + +#endif + +static void +subscription_lost_cb (G_GNUC_UNUSED GUPnPServiceProxy *proxy, + const GError *reason, + G_GNUC_UNUSED gpointer user_data) +{ + g_print ("Lost subscription: %s\n", reason->message); +} + +static void +notify_cb (G_GNUC_UNUSED GUPnPServiceProxy *proxy, + const char *variable, + GValue *value, + gpointer user_data) +{ + g_print ("Received a notification for variable '%s':\n", variable); + g_print ("\tvalue: %d\n", g_value_get_uint (value)); + g_print ("\tuser_data: %s\n", (const char *) user_data); +} + +static void +service_proxy_available_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPServiceProxy *proxy) +{ + const char *location; + char *result = NULL; + guint count, total; + GError *error = NULL; + GUPnPServiceProxyAction *action = NULL; + + location = gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy)); + + g_print ("ContentDirectory available:\n"); + g_print ("\tlocation: %s\n", location); + + /* We want to be notified whenever SystemUpdateID (of type uint) + * changes */ + gupnp_service_proxy_add_notify (proxy, + "SystemUpdateID", + G_TYPE_UINT, + notify_cb, + (gpointer) "Test"); + + /* Subscribe */ + g_signal_connect (proxy, + "subscription-lost", + G_CALLBACK (subscription_lost_cb), + NULL); + + gupnp_service_proxy_set_subscribed (proxy, TRUE); + + /* And test action IO */ + action = gupnp_service_proxy_action_new ( + "Browse", + /* IN args */ + "ObjectID", + G_TYPE_STRING, + "0", + "BrowseFlag", + G_TYPE_STRING, + "BrowseDirectChildren", + "Filter", + G_TYPE_STRING, + "*", + "StartingIndex", + G_TYPE_UINT, + 0, + "RequestedCount", + G_TYPE_UINT, + 0, + "SortCriteria", + G_TYPE_STRING, + "", + NULL); + gupnp_service_proxy_call_action (proxy, action, NULL, &error); + + if (error) { + g_printerr ("Error: %s\n", error->message); + g_error_free (error); + gupnp_service_proxy_action_unref (action); + + return; + } + + gupnp_service_proxy_action_get_result (action, + &error, + /* OUT args */ + "Result", + G_TYPE_STRING, + &result, + "NumberReturned", + G_TYPE_UINT, + &count, + "TotalMatches", + G_TYPE_UINT, + &total, + NULL); + + if (error) { + g_printerr ("Error: %s\n", error->message); + g_error_free (error); + gupnp_service_proxy_action_unref (action); + + return; + } + + g_print ("Browse returned:\n"); + g_print ("\tResult: %s\n", result); + g_print ("\tNumberReturned: %u\n", count); + g_print ("\tTotalMatches: %u\n", total); + + gupnp_service_proxy_action_unref (action); + g_free (result); +} + +static void +service_proxy_unavailable_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPServiceProxy *proxy) +{ + const char *location; + + location = gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy)); + + g_print ("ContentDirectory unavailable:\n"); + g_print ("\tlocation: %s\n", location); +} + +int +main (G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) +{ + GError *error; + GUPnPContext *context; + GUPnPControlPoint *cp; + + setlocale (LC_ALL, ""); + + error = NULL; + context = g_initable_new (GUPNP_TYPE_CONTEXT, NULL, &error, NULL); + if (error) { + g_printerr ("Error creating the GUPnP context: %s\n", + error->message); + g_error_free (error); + + return EXIT_FAILURE; + } + + /* We're interested in everything */ + cp = gupnp_control_point_new + (context, "urn:schemas-upnp-org:service:ContentDirectory:1"); + + g_signal_connect (cp, + "service-proxy-available", + G_CALLBACK (service_proxy_available_cb), + NULL); + g_signal_connect (cp, + "service-proxy-unavailable", + G_CALLBACK (service_proxy_unavailable_cb), + NULL); + + gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE); + + main_loop = g_main_loop_new (NULL, FALSE); + + /* Hook the handler for SIGTERM */ +#ifndef G_OS_WIN32 + g_unix_signal_add (SIGINT, unix_signal_handler, NULL); +#else + signal(SIGINT, interrupt_signal_handler); +#endif /* G_OS_WIN32 */ + + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + g_object_unref (cp); + g_object_unref (context); + + return EXIT_SUCCESS; +} diff --git a/examples/test-server.c b/examples/test-server.c new file mode 100644 index 0000000..940f8d9 --- /dev/null +++ b/examples/test-server.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2007 OpenedHand Ltd. + * + * Author: Jorn Baayen <jorn@openedhand.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <libgupnp/gupnp-root-device.h> +#include <libgupnp/gupnp-service.h> +#include <stdlib.h> +#include <locale.h> +#include <string.h> +#include <signal.h> + + +#ifndef G_OS_WIN32 +#include <glib-unix.h> +#endif + +GMainLoop *main_loop; + +static gboolean +unix_signal_handler (gpointer user_data) +{ + g_main_loop_quit (main_loop); + + return G_SOURCE_REMOVE; +} + + +#ifdef G_OS_WIN32 +/* + * Since in Windows this is basically called from + * the ConsoleCtrlHandler which does not share the restrictions of Unix signals + */ +static void +interrupt_signal_handler (G_GNUC_UNUSED int signum) +{ + unix_signal_handler (NULL); +} + +#endif + +static void +notify_failed_cb (G_GNUC_UNUSED GUPnPService *service, + G_GNUC_UNUSED const GList *callback_urls, + const GError *reason, + G_GNUC_UNUSED gpointer user_data) +{ + g_print ("NOTIFY failed: %s\n", reason->message); +} + +static gboolean +timeout (gpointer user_data) +{ + gupnp_service_notify (GUPNP_SERVICE (user_data), + "SystemUpdateID", + G_TYPE_UINT, + 27182818, + NULL); + + return FALSE; +} + +int +main (int argc, char **argv) +{ + GError *error; + GUPnPContext *context; + GUPnPRootDevice *dev; + GUPnPServiceInfo *content_dir; + + if (argc < 2) { + g_printerr ("Usage: %s DESCRIPTION_FILE\n", argv[0]); + + return EXIT_FAILURE; + } + + setlocale (LC_ALL, ""); + + error = NULL; + context = g_initable_new (GUPNP_TYPE_CONTEXT, NULL, &error, NULL); + if (error) { + g_printerr ("Error creating the GUPnP context: %s\n", + error->message); + g_error_free (error); + + return EXIT_FAILURE; + } + + g_print ("Running on port %d\n", gupnp_context_get_port (context)); + + /* Create root device */ + dev = gupnp_root_device_new (context, "description.xml", ".", &error); + if (error != NULL) { + g_printerr ("Error creating the GUPnP root device: %s\n", + error->message); + g_error_free (error); + + return EXIT_FAILURE; + } + + /* Implement Browse action on ContentDirectory if available */ + content_dir = gupnp_device_info_get_service + (GUPNP_DEVICE_INFO (dev), + "urn:schemas-upnp-org:service:ContentDirectory:1"); + + if (content_dir) { + gupnp_service_signals_autoconnect (GUPNP_SERVICE (content_dir), + NULL, + &error); + if (error) { + g_warning ("Failed to autoconnect signals: %s", + error->message); + + g_error_free (error); + error = NULL; + } + + g_signal_connect (content_dir, + "notify-failed", + G_CALLBACK (notify_failed_cb), + NULL); + + g_timeout_add (5000, timeout, content_dir); + } + + /* Run */ + gupnp_root_device_set_available (dev, TRUE); + + main_loop = g_main_loop_new (NULL, FALSE); + + /* Hook the handler for SIGINT */ +#ifndef G_OS_WIN32 + g_unix_signal_add (SIGINT, unix_signal_handler, NULL); +#else + signal(SIGINT, interrupt_signal_handler); +#endif /* G_OS_WIN32 */ + + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + if (content_dir) + g_object_unref (content_dir); + + g_object_unref (dev); + g_object_unref (context); + + return EXIT_SUCCESS; +} diff --git a/examples/test-white-list.c b/examples/test-white-list.c new file mode 100644 index 0000000..7e8624a --- /dev/null +++ b/examples/test-white-list.c @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2013 Intel Corporation. + * + * Author: Ludovic Ferrandis <ludovic.ferrandis@intel.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <libgupnp/gupnp-control-point.h> +#include <libgupnp/gupnp-context-manager.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> +#include <signal.h> +#include <glib.h> + +GMainLoop *main_loop; + +#ifndef G_OS_WIN32 +#include <glib-unix.h> +#endif + +static gboolean +unix_signal_handler (gpointer user_data) +{ + g_main_loop_quit (main_loop); + + return G_SOURCE_REMOVE; +} + + +#ifdef G_OS_WIN32 +/* + * Since in Windows this is basically called from + * the ConsoleCtrlHandler which does not share the restrictions of Unix signals + */ +static void +interrupt_signal_handler (G_GNUC_UNUSED int signum) +{ + unix_signal_handler (NULL); +} + +#endif +static void +device_proxy_available_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPDeviceProxy *proxy) +{ + const char *type, *location; + + type = gupnp_device_info_get_device_type (GUPNP_DEVICE_INFO (proxy)); + location = gupnp_device_info_get_location (GUPNP_DEVICE_INFO (proxy)); + + g_print ("Device available:\n"); + g_print ("\ttype: %s\n", type); + g_print ("\tlocation: %s\n", location); +} + +static void +device_proxy_unavailable_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPDeviceProxy *proxy) +{ + const char *type, *location; + + type = gupnp_device_info_get_device_type (GUPNP_DEVICE_INFO (proxy)); + location = gupnp_device_info_get_location (GUPNP_DEVICE_INFO (proxy)); + + g_print ("Device unavailable:\n"); + g_print ("\ttype: %s\n", type); + g_print ("\tlocation: %s\n", location); +} + +static void +service_proxy_available_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPServiceProxy *proxy) +{ + const char *type, *location; + + type = gupnp_service_info_get_service_type (GUPNP_SERVICE_INFO (proxy)); + location = gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy)); + + g_print ("Service available:\n"); + g_print ("\ttype: %s\n", type); + g_print ("\tlocation: %s\n", location); +} + +static void +service_proxy_unavailable_cb (G_GNUC_UNUSED GUPnPControlPoint *cp, + GUPnPServiceProxy *proxy) +{ + const char *type, *location; + + type = gupnp_service_info_get_service_type (GUPNP_SERVICE_INFO (proxy)); + location = gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy)); + + g_print ("Service unavailable:\n"); + g_print ("\ttype: %s\n", type); + g_print ("\tlocation: %s\n", location); +} + +static void +context_available_cb(GUPnPContextManager *context_manager, + GUPnPContext *context, + gpointer user_data) +{ + GUPnPControlPoint *cp; + GSSDPClient *client = GSSDP_CLIENT(context); + + g_print ("Context Available:\n"); + g_print ("\tServer ID: %s\n", gssdp_client_get_server_id (client)); + g_print ("\tInterface: %s\n", gssdp_client_get_interface (client)); + g_print ("\tHost IP : %s\n", gssdp_client_get_host_ip (client)); + g_print ("\tNetwork : %s\n", gssdp_client_get_network (client)); + g_print ("\tActive : %s\n", gssdp_client_get_active (client)? "TRUE" : "FALSE"); + + + /* We're interested in everything */ + cp = gupnp_control_point_new (context, "ssdp:all"); + + g_signal_connect (cp, + "device-proxy-available", + G_CALLBACK (device_proxy_available_cb), + NULL); + g_signal_connect (cp, + "device-proxy-unavailable", + G_CALLBACK (device_proxy_unavailable_cb), + NULL); + g_signal_connect (cp, + "service-proxy-available", + G_CALLBACK (service_proxy_available_cb), + NULL); + g_signal_connect (cp, + "service-proxy-unavailable", + G_CALLBACK (service_proxy_unavailable_cb), + NULL); + + gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE); + gupnp_context_manager_manage_control_point(context_manager, cp); + g_object_unref(cp); +} + +static void +context_unavailable_cb(GUPnPContextManager *context_manager, + GUPnPContext *context, + gpointer user_data) +{ + GSSDPClient *client = GSSDP_CLIENT(context); + + g_print ("Context Unavailable:\n"); + g_print ("\tServer ID: %s\n", gssdp_client_get_server_id (client)); + g_print ("\tInterface: %s\n", gssdp_client_get_interface (client)); + g_print ("\tHost IP : %s\n", gssdp_client_get_host_ip (client)); + g_print ("\tNetwork : %s\n", gssdp_client_get_network (client)); + g_print ("\tActive : %s\n", gssdp_client_get_active (client)? "TRUE" : "FALSE"); +} + +static void +print_wl_entry(gpointer data, gpointer user_data) +{ + g_print ("\t\t\tEntry: %s\n", (char *)data); +} + +static void +print_white_list_entries(GUPnPWhiteList *wl) +{ + GList *list; + + g_print ("\t\tWhite List Entries:\n"); + list = gupnp_white_list_get_entries(wl); + g_list_foreach (list, print_wl_entry, NULL); + g_print ("\n"); +} + +static gboolean +change_white_list(gpointer user_data) +{ + GUPnPContextManager *context_manager = user_data; + GUPnPWhiteList *white_list; + static int tomato = 0; + + g_print ("\nChange White List:\n"); + g_print ("\t Action number %d:\n", tomato); + + white_list = gupnp_context_manager_get_white_list(context_manager); + + switch (tomato) { + case 0: + g_print ("\t Add Entry eth0\n\n"); + gupnp_white_list_add_entry(white_list, "eth0"); + print_white_list_entries (white_list); + break; + case 1: + g_print ("\t Enable WL\n\n"); + gupnp_white_list_set_enabled (white_list, TRUE); + break; + case 2: + g_print ("\t Add Entry 127.0.0.1\n\n"); + gupnp_white_list_add_entry(white_list, "127.0.0.1"); + print_white_list_entries (white_list); + break; + case 3: + g_print ("\t Add Entry eth5\n\n"); + gupnp_white_list_add_entry(white_list, "eth5"); + print_white_list_entries (white_list); + break; + case 4: + g_print ("\t Remove Entry eth5\n\n"); + gupnp_white_list_remove_entry(white_list, "eth5"); + print_white_list_entries (white_list); + break; + case 5: + g_print ("\t Clear all entries\n\n"); + gupnp_white_list_clear(white_list); + print_white_list_entries (white_list); + break; + case 6: + g_print ("\t Add Entry wlan2\n\n"); + gupnp_white_list_add_entry(white_list, "wlan2"); + print_white_list_entries(white_list); + break; + case 7: + g_print ("\t Disable WL\n\n"); + gupnp_white_list_set_enabled (white_list, FALSE); + break; + case 8: + g_print ("\t Enable WL\n\n"); + gupnp_white_list_set_enabled (white_list, TRUE); + break; + case 9: + g_print ("\t Connect to wlan0\n\n"); + g_timeout_add_seconds (35, change_white_list, context_manager); + break; + case 10: + g_print ("\t Add Entry wlan0\n\n"); + gupnp_white_list_add_entry(white_list, "wlan0"); + print_white_list_entries (white_list); + break; + //~ case 11: + //~ g_print ("\t Enable WL\n"); + //~ gupnp_white_list_enable(white_list, FALSE); + //~ break; + default: + break; + } + + tomato++; + + return (tomato < 11) && (tomato != 10); +} + +int +main (G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) +{ + GUPnPContextManager *cm; + guint id; + + setlocale (LC_ALL, ""); + + cm = gupnp_context_manager_create(0); + + g_signal_connect(cm, + "context-available", + G_CALLBACK(context_available_cb), + NULL); + + g_signal_connect(cm, + "context-unavailable", + G_CALLBACK(context_unavailable_cb), + NULL); + + main_loop = g_main_loop_new (NULL, FALSE); + + id = g_timeout_add_seconds (5, change_white_list, cm); + +#ifndef G_OS_WIN32 + g_unix_signal_add (SIGINT, unix_signal_handler, NULL); +#else + signal(SIGINT, interrupt_signal_handler); +#endif /* G_OS_WIN32 */ + + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + g_source_remove (id); + + g_object_unref (cm); + + return EXIT_SUCCESS; +} |