60ce266c41c4a82cd325d8d097c1fa77398d394a
[profile/ivi/GUPnP.git] / examples / light-client.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
15 static GMainLoop *main_loop;
16
17 static enum {
18   OFF = 0,
19   ON = 1,
20   TOGGLE
21 } mode;
22
23 static void
24 service_proxy_available_cb (G_GNUC_UNUSED GUPnPControlPoint *cp,
25                             GUPnPServiceProxy               *proxy)
26 {
27   GError *error = NULL;
28   gboolean target;
29
30   if (mode == TOGGLE) {
31     /* We're toggling, so first fetch the current status */
32     if (!gupnp_service_proxy_send_action
33         (proxy, "GetStatus", &error,
34          /* IN args */ NULL,
35          /* OUT args */ "ResultStatus", G_TYPE_BOOLEAN, &target, NULL)) {
36       goto error;
37     }
38     /* And then toggle it */
39     target = ! target;
40   } else {
41     /* Mode is a boolean, so the target is the mode thanks to our well chosen
42        enumeration values. */
43     target = mode;
44   }
45
46   /* Set the target */
47   if (!gupnp_service_proxy_send_action (proxy, "SetTarget", &error,
48                                         /* IN args */
49                                         "NewTargetValue", G_TYPE_BOOLEAN, target, NULL,
50                                         /* OUT args */
51                                         NULL)) {
52     goto error;
53   } else {
54     g_print ("Set switch to %s.\n", target ? "on" : "off");
55   }
56   
57  done:
58   /* Only manipulate the first light switch that is found */
59   g_main_loop_quit (main_loop);
60   return;
61
62  error:
63   g_printerr ("Cannot set switch: %s\n", error->message);
64   g_error_free (error);
65   goto done;
66 }
67
68 static void
69 usage (void)
70 {
71     g_printerr ("$ light-client [on|off|toggle]\n");
72 }
73
74 int
75 main (int argc, char **argv)
76 {
77   GError *error = NULL;
78   GUPnPContext *context;
79   GUPnPControlPoint *cp;
80
81 #if !GLIB_CHECK_VERSION(2,35,0)
82   g_type_init ();
83 #endif
84
85
86   /* Check and parse command line arguments */
87   if (argc != 2) {
88     usage ();
89     return EXIT_FAILURE;
90   }
91   
92   if (g_str_equal (argv[1], "on")) {
93     mode = ON;
94   } else if (g_str_equal (argv[1], "off")) {
95     mode = OFF;
96   } else if (g_str_equal (argv[1], "toggle")) {
97     mode = TOGGLE;
98   } else {
99     usage ();
100     return EXIT_FAILURE;
101   }
102
103   /* Create the UPnP context */
104   context = gupnp_context_new (NULL, NULL, 0, &error);
105   if (error) {
106     g_printerr ("Error creating the GUPnP context: %s\n",
107                 error->message);
108     g_error_free (error);
109
110     return EXIT_FAILURE;
111   }
112
113   /* Create the control point, searching for SwitchPower services */
114   cp = gupnp_control_point_new (context,
115                                 "urn:schemas-upnp-org:service:SwitchPower:1");
116   
117   /* Connect to the service-found callback */
118   g_signal_connect (cp,
119                     "service-proxy-available",
120                     G_CALLBACK (service_proxy_available_cb),
121                     NULL);
122   
123   /* Start searching when the main loop runs */
124   gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE);
125
126   /* Run the main loop */
127   main_loop = g_main_loop_new (NULL, FALSE);
128   g_main_loop_run (main_loop);
129
130   /* Cleanup */
131   g_main_loop_unref (main_loop);
132   g_object_unref (cp);
133   g_object_unref (context);
134   
135   return EXIT_SUCCESS;
136 }