summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorJens Georg <mail@jensge.org>2021-05-30 12:00:42 +0200
committerJens Georg <mail@jensge.org>2021-06-09 23:55:54 +0200
commitf26b70a719272e85dcc6fdc1a0afc276ae5e106e (patch)
tree651418dd3903e519da28a69f5349e86552bd4cf3 /examples
parent433d1c1cb9fb4773a3ccda412b782d8b70c372b6 (diff)
downloadgupnp-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.build9
-rw-r--r--examples/test-browsing.c168
-rw-r--r--examples/test-introspection.c286
-rw-r--r--examples/test-proxy.c232
-rw-r--r--examples/test-server.c164
-rw-r--r--examples/test-white-list.c301
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;
+}