summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorJens Georg <mail@jensge.org>2021-05-18 17:49:39 +0200
committerJens Georg <mail@jensge.org>2021-05-24 08:03:44 +0000
commit8f33bef3bc92c3cd6f0752bbb03d8d5219d04b51 (patch)
tree3747fb479e36c6813de3676597c12a1fb9f2cafa /examples
parent098687e9b498c1dd56bb8b8cf7a4d86805801b0b (diff)
downloadgupnp-8f33bef3bc92c3cd6f0752bbb03d8d5219d04b51.tar.gz
examples: Add get-volme C example
Diffstat (limited to 'examples')
-rw-r--r--examples/get-volume.c166
-rw-r--r--examples/meson.build6
2 files changed, 172 insertions, 0 deletions
diff --git a/examples/get-volume.c b/examples/get-volume.c
new file mode 100644
index 0000000..4601014
--- /dev/null
+++ b/examples/get-volume.c
@@ -0,0 +1,166 @@
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+
+#include <glib.h>
+#include <libgupnp/gupnp.h>
+
+char CONTENT_DIR[] = "urn:schemas-upnp-org:service:RenderingControl:1";
+
+gboolean on_timeout(gpointer user_data)
+{
+ g_main_loop_quit ((GMainLoop*)(user_data));
+
+ return FALSE;
+}
+
+void
+gvalue_free (gpointer value)
+{
+ g_value_unset ((GValue *) value);
+ g_free (value);
+}
+
+void
+on_introspection (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+ GError *error = NULL;
+
+ GUPnPServiceIntrospection *i = gupnp_service_info_introspect_finish (
+ GUPNP_SERVICE_INFO (object),
+ res,
+ &error);
+
+ if (error != NULL) {
+ g_critical (error->message);
+ g_clear_error (&error);
+ }
+
+ const GUPnPServiceActionInfo *info =
+ gupnp_service_introspection_get_action (i, "GetVolume");
+ const char *state_variable_name =
+ ((GUPnPServiceActionArgInfo *) info->arguments->next->data)
+ ->related_state_variable;
+
+ const char *channel = gupnp_service_introspection_get_state_variable (
+ i,
+ state_variable_name)
+ ->allowed_values->data;
+ g_print ("Calling GetVolume for channel %s", channel);
+ GList *in_names = NULL;
+ in_names = g_list_prepend (in_names, g_strdup ("Channel"));
+ in_names = g_list_prepend (in_names, g_strdup ("InstanceID"));
+ GList *in_values = NULL;
+ GValue instance = G_VALUE_INIT;
+ g_value_init (&instance, G_TYPE_INT);
+ g_value_set_int (&instance, 0);
+ in_values = g_list_prepend (in_values, &instance);
+ GValue channel_v = G_VALUE_INIT;
+ g_value_init (&channel_v, G_TYPE_STRING);
+ g_value_set_string (&channel_v, channel);
+
+ GUPnPServiceProxyAction *a =
+ gupnp_service_proxy_action_new_from_list ("GetVolume",
+ in_names,
+ in_values);
+ g_list_free_full (in_names, g_free);
+ g_list_free (in_values);
+ g_value_unset (&channel_v);
+
+ g_boxed_copy (gupnp_service_proxy_action_get_type (), a);
+
+ gupnp_service_proxy_call_action (GUPNP_SERVICE_PROXY (object),
+ a,
+ NULL,
+ &error);
+ g_boxed_free (gupnp_service_proxy_action_get_type (), a);
+
+
+ GList *out_names = NULL;
+ out_names = g_list_prepend (out_names, "CurrentVolume");
+ GList *out_types = NULL;
+ out_types =
+ g_list_prepend (out_types, GSIZE_TO_POINTER (G_TYPE_STRING));
+ GList *out_values = NULL;
+
+
+ gupnp_service_proxy_action_get_result_list (a,
+ out_names,
+ out_types,
+ &out_values,
+ &error);
+ g_list_free (out_types);
+ g_list_free (out_names);
+
+ if (error != NULL) {
+ g_critical (error->message);
+ g_clear_error (&error);
+ } else {
+ g_print ("Current volume: %s\n",
+ g_value_get_string (out_values->data));
+ }
+ g_list_free_full (out_values, gvalue_free);
+
+ gupnp_service_proxy_action_unref (a);
+ g_object_unref (i);
+}
+
+
+void on_proxy_available (GUPnPControlPoint *cp, GUPnPServiceProxy *proxy, gpointer user_data)
+{
+ g_autofree char *id =
+ gupnp_service_info_get_id (GUPNP_SERVICE_INFO (proxy));
+
+ g_print ("Got ServiceProxy %s at %s\n",
+ id,
+ gupnp_service_info_get_location (GUPNP_SERVICE_INFO (proxy)));
+ g_print ("Introspecting service ...\n");
+ gupnp_service_info_introspect_async (GUPNP_SERVICE_INFO (proxy),
+ NULL,
+ on_introspection,
+ NULL);
+}
+
+int main(int argc, char *argv[])
+{
+ GError *error = NULL;
+ GMainLoop *loop = g_main_loop_new (NULL, FALSE);
+
+ GUPnPContext *context = gupnp_context_new ("wlp3s0", 0, &error);
+
+ if (error != NULL) {
+ g_error (error->message);
+ }
+
+ GUPnPControlPoint *cp = gupnp_control_point_new (context, CONTENT_DIR);
+ g_signal_connect (cp, "service-proxy-available", G_CALLBACK (on_proxy_available), NULL);
+ gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE);
+
+ g_timeout_add_seconds (10, on_timeout, loop);
+
+ g_main_loop_run (loop);
+
+ g_object_unref (cp);
+ g_object_unref (context);
+ g_main_loop_unref (loop);
+
+ return 0;
+}
diff --git a/examples/meson.build b/examples/meson.build
index dccd47b..c8d0d3c 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -10,3 +10,9 @@ executable(
'light-client.c',
dependencies : gupnp
)
+
+executable(
+ 'get-volume',
+ 'get-volume.c',
+ dependencies: gupnp
+)