2 * Example UPnP device/service, implementing the BinaryLight device and
3 * SwitchPower services to emulate a light switch.
5 * The user interface is as minimal as possible so that the GUPnP concepts and
6 * best practises are more apparent. For a better implementation of
7 * BinaryLight, see gupnp-tools.
9 * This example code is in the public domain.
12 #include <libgupnp/gupnp.h>
16 static gboolean status;
17 static gboolean quiet;
19 static GOptionEntry entries[] =
21 { "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, "Turn off output", NULL },
26 G_MODULE_EXPORT void set_target_cb (GUPnPService *service,
27 GUPnPServiceAction *action,
29 G_MODULE_EXPORT void get_target_cb (GUPnPService *service,
30 GUPnPServiceAction *action,
32 G_MODULE_EXPORT void get_status_cb (GUPnPService *service,
33 GUPnPServiceAction *action,
35 G_MODULE_EXPORT void query_target_cb (GUPnPService *service, char *variable,
36 GValue *value, gpointer user_data);
37 G_MODULE_EXPORT void query_status_cb (GUPnPService *service, char *variable,
38 GValue *value, gpointer user_data);
46 set_target_cb (GUPnPService *service,
47 GUPnPServiceAction *action,
48 G_GNUC_UNUSED gpointer user_data)
52 /* Get the new target value */
53 gupnp_service_action_get (action,
54 "NewTargetValue", G_TYPE_BOOLEAN, &target,
57 /* If the new target doesn't match the current status, change the status and
58 emit a notification that the status has changed. */
59 if (target != status) {
61 gupnp_service_notify (service,
62 "Status", G_TYPE_BOOLEAN, status,
67 g_print ("The light is now %s.\n", status ? "on" : "off");
71 /* Return success to the client */
72 gupnp_service_action_return (action);
77 get_target_cb (G_GNUC_UNUSED GUPnPService *service,
78 GUPnPServiceAction *action,
79 G_GNUC_UNUSED gpointer user_data)
81 gupnp_service_action_set (action,
82 "RetTargetValue", G_TYPE_BOOLEAN, status,
84 gupnp_service_action_return (action);
89 get_status_cb (G_GNUC_UNUSED GUPnPService *service,
90 GUPnPServiceAction *action,
91 G_GNUC_UNUSED gpointer user_data)
93 gupnp_service_action_set (action,
94 "ResultStatus", G_TYPE_BOOLEAN, status,
96 gupnp_service_action_return (action);
100 * State Variable query handlers
105 query_target_cb (G_GNUC_UNUSED GUPnPService *service,
106 G_GNUC_UNUSED char *variable,
108 G_GNUC_UNUSED gpointer user_data)
110 g_value_init (value, G_TYPE_BOOLEAN);
111 g_value_set_boolean (value, status);
116 query_status_cb (G_GNUC_UNUSED GUPnPService *service,
117 G_GNUC_UNUSED char *variable,
119 G_GNUC_UNUSED gpointer user_data)
121 g_value_init (value, G_TYPE_BOOLEAN);
122 g_value_set_boolean (value, status);
127 main (G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
129 GOptionContext *optionContext;
130 GMainLoop *main_loop;
131 GError *error = NULL;
132 GUPnPContext *context;
133 GUPnPRootDevice *dev;
134 GUPnPServiceInfo *service;
136 #if !GLIB_CHECK_VERSION(2,35,0)
140 optionContext = g_option_context_new (NULL);
141 g_option_context_add_main_entries (optionContext, entries, NULL);
142 if (!g_option_context_parse (optionContext, &argc, &argv, &error))
144 g_print ("option parsing failed: %s\n", error->message);
148 /* By default the light is off */
152 g_print ("The light is now %s.\n", status ? "on" : "off");
155 /* Create the UPnP context */
156 context = gupnp_context_new (NULL, NULL, 0, &error);
158 g_printerr ("Error creating the GUPnP context: %s\n",
160 g_error_free (error);
165 /* Create root device */
166 dev = gupnp_root_device_new (context, "BinaryLight1.xml", ".");
167 gupnp_root_device_set_available (dev, TRUE);
169 /* Get the switch service from the root device */
170 service = gupnp_device_info_get_service
171 (GUPNP_DEVICE_INFO (dev), "urn:schemas-upnp-org:service:SwitchPower:1");
173 g_printerr ("Cannot get SwitchPower1 service\n");
178 /* Autoconnect the action and state variable handlers. This connects
179 query_target_cb and query_status_cb to the Target and Status state
180 variables query callbacks, and set_target_cb, get_target_cb and
181 get_status_cb to SetTarget, GetTarget and GetStatus actions
183 gupnp_service_signals_autoconnect (GUPNP_SERVICE (service), NULL, &error);
185 g_printerr ("Failed to autoconnect signals: %s\n", error->message);
186 g_error_free (error);
191 /* Run the main loop */
192 main_loop = g_main_loop_new (NULL, FALSE);
193 g_main_loop_run (main_loop);
196 g_main_loop_unref (main_loop);
197 g_object_unref (service);
198 g_object_unref (dev);
199 g_object_unref (context);