summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorRoss Burton <ross@openedhand.com>2008-06-09 13:42:14 +0000
committerRoss Burton <ross@openedhand.com>2008-06-09 13:42:14 +0000
commitce9c398e01e3c7aa4ae49f9bf34b92cc8374817b (patch)
treeb62a04dfc60901b30ee3333993e2d8b90791d051 /examples
parent32612c9952d3a3e95e6cc2282a55c6bd6114d32b (diff)
downloadgupnp-ce9c398e01e3c7aa4ae49f9bf34b92cc8374817b.tar.gz
2008-06-09 Ross Burton <ross@openedhand.com>
* examples/: * Makefile.am: * configure.ac: Add some basic but non-trivial examples. git-svn-id: https://svn.o-hand.com/repos/gupnp/trunk/gupnp@1042 d8cb91d7-bff9-0310-92b9-80b65e4482b2
Diffstat (limited to 'examples')
-rw-r--r--examples/BinaryLight1.xml25
-rw-r--r--examples/Makefile.am11
-rw-r--r--examples/SwitchPower1.xml51
-rw-r--r--examples/light-client.c127
-rw-r--r--examples/light-server.c143
5 files changed, 357 insertions, 0 deletions
diff --git a/examples/BinaryLight1.xml b/examples/BinaryLight1.xml
new file mode 100644
index 0000000..07798b1
--- /dev/null
+++ b/examples/BinaryLight1.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root xmlns="urn:schemas-upnp-org:device-1-0">
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+
+ <device>
+ <deviceType>urn:schemas-upnp-org:device:BinaryLight:1</deviceType>
+ <friendlyName>Test Light</friendlyName>
+ <manufacturer>OpenedHand</manufacturer>
+ <modelName>Test Light</modelName>
+ <UDN>uuid:cc93d8e6-6b8b-4f60-87ca-228c36b5b0e8</UDN>
+
+ <serviceList>
+ <service>
+ <serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>
+ <serviceId>urn:upnp-org:serviceId:SwitchPower:1</serviceId>
+ <SCPDURL>/SwitchPower1.xml</SCPDURL>
+ <controlURL>/SwitchPower/Control</controlURL>
+ <eventSubURL>/SwitchPower/Event</eventSubURL>
+ </service>
+ </serviceList>
+ </device>
+</root>
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..90b1cde
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,11 @@
+AM_CFLAGS = $(LIBGUPNP_CFLAGS) -I$(top_srcdir)
+LDADD = $(top_builddir)/libgupnp/libgupnp-1.0.la
+
+noinst_PROGRAMS = light-server light-client
+
+light_server_SOURCES = light-server.c
+light_server_LDFLAGS = -export-dynamic
+
+light_client_SOURCES = light-client.c
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/examples/SwitchPower1.xml b/examples/SwitchPower1.xml
new file mode 100644
index 0000000..0204b15
--- /dev/null
+++ b/examples/SwitchPower1.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<scpd xmlns="urn:schemas-upnp-org:service-1-0">
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <actionList>
+ <action>
+ <name>SetTarget</name>
+ <argumentList>
+ <argument>
+ <name>NewTargetValue</name>
+ <relatedStateVariable>Target</relatedStateVariable>
+ <direction>in</direction>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetTarget</name>
+ <argumentList>
+ <argument>
+ <name>RetTargetValue</name>
+ <relatedStateVariable>Target</relatedStateVariable>
+ <direction>out</direction>
+ </argument>
+ </argumentList>
+ </action>
+ <action>
+ <name>GetStatus</name>
+ <argumentList>
+ <argument>
+ <name>ResultStatus</name>
+ <relatedStateVariable>Status</relatedStateVariable>
+ <direction>out</direction>
+ </argument>
+ </argumentList>
+ </action>
+ </actionList>
+ <serviceStateTable>
+ <stateVariable sendEvents="no">
+ <name>Target</name>
+ <dataType>boolean</dataType>
+ <defaultValue>0</defaultValue>
+ </stateVariable>
+ <stateVariable sendEvents="yes">
+ <name>Status</name>
+ <dataType>boolean</dataType>
+ <defaultValue>0</defaultValue>
+ </stateVariable>
+ </serviceStateTable>
+</scpd>
diff --git a/examples/light-client.c b/examples/light-client.c
new file mode 100644
index 0000000..af1df80
--- /dev/null
+++ b/examples/light-client.c
@@ -0,0 +1,127 @@
+/*
+ * Example UPnP device/service, implementing the BinaryLight device and
+ * SwitchPower services to emulate a light switch.
+ *
+ * The user interface is as minimal as possible so that the GUPnP concepts and
+ * best practises are more apparent. For a better implementation of
+ * BinaryLight, see gupnp-tools.
+ *
+ * This example code is in the public domain.
+ */
+
+#include <libgupnp/gupnp.h>
+
+static GMainLoop *main_loop;
+
+static enum {
+ OFF = 0,
+ ON = 1,
+ TOGGLE
+} mode;
+
+static void
+service_proxy_available_cb (GUPnPControlPoint *cp, GUPnPServiceProxy *proxy)
+{
+ GError *error = NULL;
+ gboolean target;
+
+ if (mode == TOGGLE) {
+ /* We're toggling, so first fetch the current status */
+ if (!gupnp_service_proxy_send_action
+ (proxy, "GetStatus", &error,
+ /* IN args */ NULL,
+ /* OUT args */ "ResultStatus", G_TYPE_BOOLEAN, &target, NULL)) {
+ goto error;
+ }
+ /* And then toggle it */
+ target = ! target;
+ } else {
+ /* Mode is a boolean, so the target is the mode thanks to our well chosen
+ enumeration values. */
+ target = mode;
+ }
+
+ /* Set the target */
+ if (!gupnp_service_proxy_send_action (proxy, "SetTarget", &error,
+ /* IN args */
+ "NewTargetValue", G_TYPE_BOOLEAN, target, NULL,
+ /* OUT args */
+ NULL)) {
+ goto error;
+ } else {
+ g_print ("Set switch to %s.\n", target ? "on" : "off");
+ }
+
+ done:
+ /* Only manipulate the first light switch that is found */
+ g_main_loop_quit (main_loop);
+ return;
+
+ error:
+ g_printerr ("Cannot set switch: %s\n", error->message);
+ g_error_free (error);
+ goto done;
+}
+
+static void
+usage (void)
+{
+ g_printerr ("$ light-client [on|off|toggle]\n");
+}
+
+int
+main (int argc, char **argv)
+{
+ GError *error = NULL;
+ GUPnPContext *context;
+ GUPnPControlPoint *cp;
+
+ g_thread_init (NULL);
+ g_type_init ();
+
+ /* Check and parse command line arguments */
+ if (argc != 2) {
+ usage ();
+ return 1;
+ }
+
+ if (g_str_equal (argv[1], "on")) {
+ mode = ON;
+ } else if (g_str_equal (argv[1], "off")) {
+ mode = OFF;
+ } else if (g_str_equal (argv[1], "toggle")) {
+ mode = TOGGLE;
+ } else {
+ usage ();
+ return 1;
+ }
+
+ /* Create the UPnP context */
+ context = gupnp_context_new (NULL, NULL, 0, &error);
+ if (error) {
+ g_error (error->message);
+ }
+
+ /* Create the control point, searching for SwitchPower services */
+ cp = gupnp_control_point_new (context, "urn:schemas-upnp-org:service:SwitchPower:1");
+
+ /* Connect to the service-found callback */
+ g_signal_connect (cp,
+ "service-proxy-available",
+ G_CALLBACK (service_proxy_available_cb),
+ NULL);
+
+ /* Start searching when the main loop runs */
+ gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE);
+
+ /* Run the main loop */
+ main_loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (main_loop);
+
+ /* Cleanup */
+ g_main_loop_unref (main_loop);
+ g_object_unref (cp);
+ g_object_unref (context);
+
+ return EXIT_SUCCESS;
+}
diff --git a/examples/light-server.c b/examples/light-server.c
new file mode 100644
index 0000000..c132032
--- /dev/null
+++ b/examples/light-server.c
@@ -0,0 +1,143 @@
+/*
+ * Example UPnP device/service, implementing the BinaryLight device and
+ * SwitchPower services to emulate a light switch.
+ *
+ * The user interface is as minimal as possible so that the GUPnP concepts and
+ * best practises are more apparent. For a better implementation of
+ * BinaryLight, see gupnp-tools.
+ *
+ * This example code is in the public domain.
+ */
+
+#include <libgupnp/gupnp.h>
+
+static gboolean status;
+
+/*
+ * Action handlers
+ */
+
+/* SetTarget */
+void
+set_target_cb (GUPnPService *service, GUPnPServiceAction *action, gpointer user_data)
+{
+ gboolean target;
+
+ /* Get the new target value */
+ gupnp_service_action_get (action,
+ "NewTargetValue", G_TYPE_BOOLEAN, &target,
+ NULL);
+
+ /* If the new target doesn't match the current status, change the status and
+ emit a notification that the status has changed. */
+ if (target != status) {
+ status = target;
+ gupnp_service_notify (service,
+ "Status", G_TYPE_BOOLEAN, status,
+ NULL);
+
+ g_print ("The light is now %s.\n", status ? "on" : "off");
+ }
+
+ /* Return success to the client */
+ gupnp_service_action_return (action);
+}
+
+/* GetTarget */
+void
+get_target_cb (GUPnPService *service, GUPnPServiceAction *action, gpointer user_data)
+{
+ gupnp_service_action_set (action,
+ "RetTargetValue", G_TYPE_BOOLEAN, status,
+ NULL);
+ gupnp_service_action_return (action);
+}
+
+/* GetStatus */
+void
+get_status_cb (GUPnPService *service, GUPnPServiceAction *action, gpointer user_data)
+{
+ gupnp_service_action_set (action,
+ "ResultStatus", G_TYPE_BOOLEAN, status,
+ NULL);
+ gupnp_service_action_return (action);
+}
+
+/*
+ * State Variable query handlers
+ */
+
+/* Target */
+void
+query_target_cb (GUPnPService *service, char *variable, GValue *value, gpointer user_data)
+{
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, status);
+}
+
+/* Status */
+void
+query_status_cb (GUPnPService *service, char *variable, GValue *value, gpointer user_data)
+{
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, status);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ GMainLoop *main_loop;
+ GError *error = NULL;
+ GUPnPContext *context;
+ GUPnPRootDevice *dev;
+ GUPnPServiceInfo *service;
+
+ g_thread_init (NULL);
+ g_type_init ();
+
+ /* By default the light is off */
+ status = FALSE;
+ g_print ("The light is now %s.\n", status ? "on" : "off");
+
+ /* Create the UPnP context */
+ context = gupnp_context_new (NULL, NULL, 0, &error);
+ if (error) {
+ g_error (error->message);
+ }
+
+ /* Host the device and service description files */
+ gupnp_context_host_path (context, "BinaryLight1.xml", "/BinaryLight1.xml");
+ gupnp_context_host_path (context, "SwitchPower1.xml", "/SwitchPower1.xml");
+
+ /* Create root device */
+ dev = gupnp_root_device_new (context, "/BinaryLight1.xml");
+ gupnp_root_device_set_available (dev, TRUE);
+
+ /* Get the switch service from the root device */
+ service = gupnp_device_info_get_service
+ (GUPNP_DEVICE_INFO (dev), "urn:schemas-upnp-org:service:SwitchPower:1");
+ if (!service)
+ g_error ("Cannot get SwitchPower1 service");
+
+ /* Autoconnect the action and state variable handlers. This connects
+ query_target_cb and query_status_cb to the Target and Status state
+ variables query callbacks, and set_target_cb, get_target_cb and
+ get_status_cb to SetTarget, GetTarget and GetStatus actions
+ respectively. */
+ gupnp_service_signals_autoconnect (GUPNP_SERVICE (service), NULL, &error);
+ if (error)
+ g_error ("Failed to autoconnect signals: %s", error->message);
+
+ /* Run the main loop */
+ main_loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (main_loop);
+
+ /* Cleanup */
+ g_main_loop_unref (main_loop);
+ g_object_unref (service);
+ g_object_unref (dev);
+ g_object_unref (context);
+
+ return EXIT_SUCCESS;
+}