Imported Upstream version 0.20.12
[profile/ivi/GUPnP.git] / examples / light-server.c
1 /*
2  * Example UPnP device/service, implementing the BinaryLight device and
3  * SwitchPower services to emulate a light switch.
4  *
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.
8  *
9  * This example code is in the public domain.
10  */
11
12 #include <libgupnp/gupnp.h>
13 #include <stdlib.h>
14 #include <gmodule.h>
15
16 static gboolean status;
17 static gboolean quiet;
18
19 static GOptionEntry entries[] =
20 {
21   { "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, "Turn off output", NULL },
22   { NULL }
23 };
24
25 G_BEGIN_DECLS
26 G_MODULE_EXPORT void set_target_cb (GUPnPService *service,
27                                     GUPnPServiceAction *action,
28                                     gpointer user_data);
29 G_MODULE_EXPORT void get_target_cb (GUPnPService *service,
30                                     GUPnPServiceAction *action,
31                                     gpointer user_data);
32 G_MODULE_EXPORT void get_status_cb (GUPnPService *service,
33                                     GUPnPServiceAction *action,
34                                     gpointer user_data);
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);
39 G_END_DECLS
40 /*
41  * Action handlers
42  */
43
44 /* SetTarget */
45 G_MODULE_EXPORT void
46 set_target_cb (GUPnPService          *service,
47                GUPnPServiceAction    *action,
48                G_GNUC_UNUSED gpointer user_data)
49 {
50   gboolean target;
51
52   /* Get the new target value */
53   gupnp_service_action_get (action,
54                             "NewTargetValue", G_TYPE_BOOLEAN, &target,
55                             NULL);
56
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) {
60     status = target;
61     gupnp_service_notify (service,
62                           "Status", G_TYPE_BOOLEAN, status,
63                           NULL);
64
65     if (!quiet)
66     {
67       g_print ("The light is now %s.\n", status ? "on" : "off");
68     }
69   }
70
71   /* Return success to the client */
72   gupnp_service_action_return (action);
73 }
74
75 /* GetTarget */
76 G_MODULE_EXPORT void
77 get_target_cb (G_GNUC_UNUSED GUPnPService *service,
78                GUPnPServiceAction         *action,
79                G_GNUC_UNUSED gpointer      user_data)
80 {
81   gupnp_service_action_set (action,
82                             "RetTargetValue", G_TYPE_BOOLEAN, status,
83                             NULL);
84   gupnp_service_action_return (action);
85 }
86
87 /* GetStatus */
88 G_MODULE_EXPORT void
89 get_status_cb (G_GNUC_UNUSED GUPnPService *service,
90                GUPnPServiceAction         *action,
91                G_GNUC_UNUSED gpointer      user_data)
92 {
93   gupnp_service_action_set (action,
94                             "ResultStatus", G_TYPE_BOOLEAN, status,
95                             NULL);
96   gupnp_service_action_return (action);
97 }
98
99 /*
100  * State Variable query handlers
101  */
102
103 /* Target */
104 G_MODULE_EXPORT void
105 query_target_cb (G_GNUC_UNUSED GUPnPService *service,
106                  G_GNUC_UNUSED char         *variable,
107                  GValue                     *value,
108                  G_GNUC_UNUSED gpointer      user_data)
109 {
110   g_value_init (value, G_TYPE_BOOLEAN);
111   g_value_set_boolean (value, status);
112 }
113
114 /* Status */
115 G_MODULE_EXPORT void
116 query_status_cb (G_GNUC_UNUSED GUPnPService *service,
117                  G_GNUC_UNUSED char         *variable,
118                  GValue                     *value,
119                  G_GNUC_UNUSED gpointer      user_data)
120 {
121   g_value_init (value, G_TYPE_BOOLEAN);
122   g_value_set_boolean (value, status);
123 }
124
125
126 int
127 main (G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
128 {
129   GOptionContext *optionContext;
130   GMainLoop *main_loop;
131   GError *error = NULL;
132   GUPnPContext *context;
133   GUPnPRootDevice *dev;
134   GUPnPServiceInfo *service;
135   
136 #if !GLIB_CHECK_VERSION(2,35,0)
137   g_type_init ();
138 #endif
139
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))
143   {
144     g_print ("option parsing failed: %s\n", error->message);
145     exit (1);
146   }
147
148   /* By default the light is off */
149   status = FALSE;
150   if (!quiet)
151   {
152     g_print ("The light is now %s.\n", status ? "on" : "off");
153   }
154
155   /* Create the UPnP context */
156   context = gupnp_context_new (NULL, NULL, 0, &error);
157   if (error) {
158     g_printerr ("Error creating the GUPnP context: %s\n",
159                 error->message);
160     g_error_free (error);
161
162     return EXIT_FAILURE;
163   }
164
165   /* Create root device */
166   dev = gupnp_root_device_new (context, "BinaryLight1.xml", ".");
167   gupnp_root_device_set_available (dev, TRUE);
168
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");
172   if (!service) {
173     g_printerr ("Cannot get SwitchPower1 service\n");
174
175     return EXIT_FAILURE;
176   }
177   
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
182      respectively. */
183   gupnp_service_signals_autoconnect (GUPNP_SERVICE (service), NULL, &error);
184   if (error) {
185     g_printerr ("Failed to autoconnect signals: %s\n", error->message);
186     g_error_free (error);
187
188     return EXIT_FAILURE;
189   }
190   
191   /* Run the main loop */
192   main_loop = g_main_loop_new (NULL, FALSE);
193   g_main_loop_run (main_loop);
194
195   /* Cleanup */
196   g_main_loop_unref (main_loop);
197   g_object_unref (service);
198   g_object_unref (dev);
199   g_object_unref (context);
200   
201   return EXIT_SUCCESS;
202 }