<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Implementing the BinaryLight device</title> </head> <body><div class="manualnavbar" style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="gupnp.browsing.html">Browsing devices and services</a></div> <div class="next" style="text-align: right; float: right;"><a href="ref.gupnp.html">Gupnp Functions</a></div> <div class="up"><a href="gupnp.examples.html">Examples</a></div> <div class="home"><a href="index.html">PHP Manual</a></div> </div><hr /><div id="gupnp.binary-light" class="section"> <h2 class="title">Implementing the BinaryLight device</h2> <p class="para"> This is an example of UPnP device/service, implementing the BinaryLight device and SwitchPower services to emulate a light switch. </p> <p class="para"> The user interface was purposely simplified in order to show basic concepts and methods. </p> <p class="para"> <div class="example" id="example-4338"> <p><strong>Example #1 Implementing light server</strong></p> <div class="example-contents"> <div class="phpcode"><code><span style="color: #000000"> <span style="color: #0000BB"><?php<br /><br /></span><span style="color: #FF8000">/* SetTarget */<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">set_target_cb</span><span style="color: #007700">(</span><span style="color: #0000BB">$service</span><span style="color: #007700">, </span><span style="color: #0000BB">$action</span><span style="color: #007700">, </span><span style="color: #0000BB">$arg</span><span style="color: #007700">)<br />{<br /> </span><span style="color: #FF8000">/* Get the new target value */<br /> </span><span style="color: #0000BB">$target </span><span style="color: #007700">= </span><span style="color: #0000BB">gupnp_service_action_get</span><span style="color: #007700">(</span><span style="color: #0000BB">$action</span><span style="color: #007700">, </span><span style="color: #DD0000">'NewTargetValue'</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_TYPE_BOOLEAN</span><span style="color: #007700">);<br /><br /> </span><span style="color: #FF8000">/* If the new target doesn't match the current status, change the status and<br /> emit a notification that the status has changed. */<br /> </span><span style="color: #007700">if (</span><span style="color: #0000BB">$target </span><span style="color: #007700">!= </span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'status'</span><span style="color: #007700">]) {<br /> </span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'status'</span><span style="color: #007700">] = </span><span style="color: #0000BB">$target</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">gupnp_service_notify</span><span style="color: #007700">(</span><span style="color: #0000BB">$service</span><span style="color: #007700">, </span><span style="color: #DD0000">'Status'</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_TYPE_BOOLEAN</span><span style="color: #007700">, </span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'status'</span><span style="color: #007700">]);<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"The light is now %s.\n"</span><span style="color: #007700">, </span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'status'</span><span style="color: #007700">] ? </span><span style="color: #DD0000">"on" </span><span style="color: #007700">: </span><span style="color: #DD0000">"off"</span><span style="color: #007700">);<br /> }<br /><br /> </span><span style="color: #FF8000">/* Return success to the client */<br /> </span><span style="color: #0000BB">gupnp_service_action_return</span><span style="color: #007700">(</span><span style="color: #0000BB">$action</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #FF8000">/* GetTarget */<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">get_target_cb</span><span style="color: #007700">(</span><span style="color: #0000BB">$service</span><span style="color: #007700">, </span><span style="color: #0000BB">$action</span><span style="color: #007700">, </span><span style="color: #0000BB">$arg</span><span style="color: #007700">)<br />{<br /> </span><span style="color: #0000BB">gupnp_service_action_set</span><span style="color: #007700">(</span><span style="color: #0000BB">$action</span><span style="color: #007700">, </span><span style="color: #DD0000">'RetTargetValue'</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_TYPE_BOOLEAN</span><span style="color: #007700">, </span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'status'</span><span style="color: #007700">]);<br /> </span><span style="color: #0000BB">gupnp_service_action_return</span><span style="color: #007700">(</span><span style="color: #0000BB">$action</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #FF8000">/* GetStatus */<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">get_status_cb</span><span style="color: #007700">(</span><span style="color: #0000BB">$service</span><span style="color: #007700">, </span><span style="color: #0000BB">$action</span><span style="color: #007700">, </span><span style="color: #0000BB">$arg</span><span style="color: #007700">)<br />{<br /> </span><span style="color: #0000BB">gupnp_service_action_set</span><span style="color: #007700">(</span><span style="color: #0000BB">$action</span><span style="color: #007700">, </span><span style="color: #DD0000">'ResultStatus'</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_TYPE_BOOLEAN</span><span style="color: #007700">, </span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'status'</span><span style="color: #007700">]);<br /> </span><span style="color: #0000BB">gupnp_service_action_return</span><span style="color: #007700">(</span><span style="color: #0000BB">$action</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #FF8000">/* By default the light is off */<br /></span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'status'</span><span style="color: #007700">] = </span><span style="color: #0000BB">false</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"The light is now %s.\n"</span><span style="color: #007700">, </span><span style="color: #0000BB">$GLOBALS</span><span style="color: #007700">[</span><span style="color: #DD0000">'status'</span><span style="color: #007700">] ? </span><span style="color: #DD0000">"on" </span><span style="color: #007700">: </span><span style="color: #DD0000">"off"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Create the UPnP context */<br /></span><span style="color: #0000BB">$context </span><span style="color: #007700">= </span><span style="color: #0000BB">gupnp_context_new</span><span style="color: #007700">();<br />if (!</span><span style="color: #0000BB">$context</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"Error creating the GUPnP context\n"</span><span style="color: #007700">);<br /> exit(-</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #FF8000">/* Host the directory that contains device and service description files */<br /></span><span style="color: #0000BB">gupnp_context_host_path</span><span style="color: #007700">(</span><span style="color: #0000BB">$context</span><span style="color: #007700">, </span><span style="color: #DD0000">"./web"</span><span style="color: #007700">, </span><span style="color: #DD0000">""</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Create root device */<br /></span><span style="color: #0000BB">$location </span><span style="color: #007700">= </span><span style="color: #DD0000">"/BinaryLight.xml"</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$dev </span><span style="color: #007700">= </span><span style="color: #0000BB">gupnp_root_device_new</span><span style="color: #007700">(</span><span style="color: #0000BB">$context</span><span style="color: #007700">, </span><span style="color: #0000BB">$location</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">gupnp_root_device_set_available</span><span style="color: #007700">(</span><span style="color: #0000BB">$dev</span><span style="color: #007700">, </span><span style="color: #0000BB">true</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Get the switch service from the root device */<br /></span><span style="color: #0000BB">$service_type </span><span style="color: #007700">= </span><span style="color: #DD0000">"urn:schemas-upnp-org:service:SwitchPower:1"</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$service </span><span style="color: #007700">= </span><span style="color: #0000BB">gupnp_device_info_get_service</span><span style="color: #007700">(</span><span style="color: #0000BB">$dev</span><span style="color: #007700">, </span><span style="color: #0000BB">$service_type</span><span style="color: #007700">);<br />if (!</span><span style="color: #0000BB">$service</span><span style="color: #007700">) {<br /> die(</span><span style="color: #DD0000">"Cannot get SwitchPower1 service\n"</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #FF8000">/* Set callback for action GetStatus */<br /></span><span style="color: #0000BB">gupnp_device_action_callback_set</span><span style="color: #007700">(</span><span style="color: #0000BB">$service</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_SIGNAL_ACTION_INVOKED</span><span style="color: #007700">, </span><span style="color: #DD0000">"GetStatus"</span><span style="color: #007700">, <br /> </span><span style="color: #DD0000">"get_status_cb"</span><span style="color: #007700">, </span><span style="color: #DD0000">"action data, GetStatus"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Set callback for action GetTarget */<br /></span><span style="color: #0000BB">gupnp_device_action_callback_set</span><span style="color: #007700">(</span><span style="color: #0000BB">$service</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_SIGNAL_ACTION_INVOKED</span><span style="color: #007700">, </span><span style="color: #DD0000">"GetTarget"</span><span style="color: #007700">, <br /> </span><span style="color: #DD0000">"get_target_cb"</span><span style="color: #007700">, </span><span style="color: #DD0000">"action data, GetTarget"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Set callback for action SetTarget */<br /></span><span style="color: #0000BB">gupnp_device_action_callback_set</span><span style="color: #007700">(</span><span style="color: #0000BB">$service</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_SIGNAL_ACTION_INVOKED</span><span style="color: #007700">, </span><span style="color: #DD0000">"SetTarget"</span><span style="color: #007700">, <br /> </span><span style="color: #DD0000">"set_target_cb"</span><span style="color: #007700">, </span><span style="color: #DD0000">"action data, SetTarget"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Run the main loop */<br /></span><span style="color: #0000BB">gupnp_root_device_start</span><span style="color: #007700">(</span><span style="color: #0000BB">$dev</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?></span> </span> </code></div> </div> </div> <div class="example" id="example-4339"> <p><strong>Example #2 Implementing light client</strong></p> <div class="example-contents"> <div class="phpcode"><code><span style="color: #000000"> <span style="color: #0000BB"><?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">service_proxy_available_cb</span><span style="color: #007700">(</span><span style="color: #0000BB">$proxy</span><span style="color: #007700">, </span><span style="color: #0000BB">$arg</span><span style="color: #007700">)<br />{<br /> </span><span style="color: #0000BB">$mode </span><span style="color: #007700">= </span><span style="color: #0000BB">$arg</span><span style="color: #007700">[</span><span style="color: #DD0000">'mode'</span><span style="color: #007700">];<br /><br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"Set subscribed\n"</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">gupnp_service_proxy_set_subscribed</span><span style="color: #007700">(</span><span style="color: #0000BB">$proxy</span><span style="color: #007700">, </span><span style="color: #0000BB">true</span><span style="color: #007700">);<br /><br /> </span><span style="color: #FF8000">/* Add notify if status will be changed */<br /> </span><span style="color: #007700">if (!</span><span style="color: #0000BB">gupnp_service_proxy_add_notify</span><span style="color: #007700">(</span><span style="color: #0000BB">$proxy</span><span style="color: #007700">, </span><span style="color: #DD0000">"Status"</span><span style="color: #007700">, <br /> </span><span style="color: #0000BB">GUPNP_TYPE_BOOLEAN</span><span style="color: #007700">, </span><span style="color: #DD0000">"status_changed_cb"</span><span style="color: #007700">, </span><span style="color: #0000BB">NULL</span><span style="color: #007700">)) {<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"Failed to add notify\n"</span><span style="color: #007700">);<br /> }<br /> <br /> if (</span><span style="color: #0000BB">$mode </span><span style="color: #007700">== </span><span style="color: #DD0000">'TOGGLE'</span><span style="color: #007700">) {<br /> </span><span style="color: #FF8000">/* We're toggling, so first fetch the current status */<br /> </span><span style="color: #0000BB">$target </span><span style="color: #007700">= </span><span style="color: #0000BB">gupnp_service_proxy_action_get</span><span style="color: #007700">(</span><span style="color: #0000BB">$proxy</span><span style="color: #007700">, </span><span style="color: #DD0000">'GetStatus'</span><span style="color: #007700">, </span><span style="color: #DD0000">'ResultStatus'</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_TYPE_BOOLEAN</span><span style="color: #007700">);<br /><br /> </span><span style="color: #FF8000">/* And then toggle it */<br /> </span><span style="color: #0000BB">$target </span><span style="color: #007700">= ! </span><span style="color: #0000BB">$target</span><span style="color: #007700">;<br /> } else {<br /> </span><span style="color: #FF8000">/* Mode is a boolean, so the target is the mode thanks to our well chosen<br /> enumeration values. */<br /> </span><span style="color: #0000BB">$target </span><span style="color: #007700">= (</span><span style="color: #0000BB">$mode </span><span style="color: #007700">== </span><span style="color: #DD0000">'ON'</span><span style="color: #007700">) ? </span><span style="color: #0000BB">true </span><span style="color: #007700">: </span><span style="color: #0000BB">false</span><span style="color: #007700">;<br /> }<br /><br /> </span><span style="color: #FF8000">/* Set the target */<br /> </span><span style="color: #007700">if (!</span><span style="color: #0000BB">gupnp_service_proxy_action_set</span><span style="color: #007700">(</span><span style="color: #0000BB">$proxy</span><span style="color: #007700">, </span><span style="color: #DD0000">'SetTarget'</span><span style="color: #007700">, </span><span style="color: #DD0000">'NewTargetValue'</span><span style="color: #007700">, </span><span style="color: #0000BB">$target</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_TYPE_BOOLEAN</span><span style="color: #007700">)) {<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"Cannot set switch\n"</span><span style="color: #007700">);<br /> } else {<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"Set switch to %s.\n"</span><span style="color: #007700">, </span><span style="color: #0000BB">$target </span><span style="color: #007700">? </span><span style="color: #DD0000">"on" </span><span style="color: #007700">: </span><span style="color: #DD0000">"off"</span><span style="color: #007700">);<br /> }<br /> <br /> </span><span style="color: #FF8000">/* Stop browsing */<br /> </span><span style="color: #0000BB">gupnp_control_point_browse_stop</span><span style="color: #007700">(</span><span style="color: #0000BB">$arg</span><span style="color: #007700">[</span><span style="color: #DD0000">'cp'</span><span style="color: #007700">]);<br />}<br /><br />function </span><span style="color: #0000BB">status_changed_cb</span><span style="color: #007700">(</span><span style="color: #0000BB">$variable</span><span style="color: #007700">, </span><span style="color: #0000BB">$value</span><span style="color: #007700">, </span><span style="color: #0000BB">$arg</span><span style="color: #007700">)<br />{<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"Status has been changed\n"</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"\tvariable name: %s\n"</span><span style="color: #007700">, </span><span style="color: #0000BB">$variable</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"\tvalue: %s\n"</span><span style="color: #007700">, (int)</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"\n"</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #FF8000">/* Check and parse command line arguments */<br /></span><span style="color: #007700">if (</span><span style="color: #0000BB">count</span><span style="color: #007700">(</span><span style="color: #0000BB">$argv</span><span style="color: #007700">) != </span><span style="color: #0000BB">2</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"Usage: light-client.php [on|off|toggle]\n"</span><span style="color: #007700">);<br /> exit(-</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br />}<br /><br />if (</span><span style="color: #0000BB">$argv</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">] == </span><span style="color: #DD0000">"on"</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">$mode </span><span style="color: #007700">= </span><span style="color: #DD0000">'ON'</span><span style="color: #007700">;<br />} elseif (</span><span style="color: #0000BB">$argv</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">] == </span><span style="color: #DD0000">"off"</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">$mode </span><span style="color: #007700">= </span><span style="color: #DD0000">'OFF'</span><span style="color: #007700">;<br />} elseif (</span><span style="color: #0000BB">$argv</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">] == </span><span style="color: #DD0000">"toggle"</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">$mode </span><span style="color: #007700">= </span><span style="color: #DD0000">'TOGGLE'</span><span style="color: #007700">;<br />} else {<br /> </span><span style="color: #0000BB">usage </span><span style="color: #007700">();<br /> exit(-</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #FF8000">/* Create the UPnP context */<br /></span><span style="color: #0000BB">$context </span><span style="color: #007700">= </span><span style="color: #0000BB">gupnp_context_new</span><span style="color: #007700">();<br />if (!</span><span style="color: #0000BB">$context</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"Error creating the GUPnP context\n"</span><span style="color: #007700">);<br /> exit(-</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br />}<br /><br /></span><span style="color: #FF8000">/* Create the control point, searching for SwitchPower services */<br /></span><span style="color: #0000BB">$cp </span><span style="color: #007700">= </span><span style="color: #0000BB">gupnp_control_point_new </span><span style="color: #007700">(</span><span style="color: #0000BB">$context</span><span style="color: #007700">,<br /> </span><span style="color: #DD0000">"urn:schemas-upnp-org:service:SwitchPower:1"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Connect to the service-found callback */<br /></span><span style="color: #0000BB">$cb </span><span style="color: #007700">= </span><span style="color: #DD0000">"service_proxy_available_cb"</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$arg </span><span style="color: #007700">= array(</span><span style="color: #DD0000">'mode' </span><span style="color: #007700">=> </span><span style="color: #0000BB">$mode</span><span style="color: #007700">, </span><span style="color: #DD0000">'cp' </span><span style="color: #007700">=> </span><span style="color: #0000BB">$cp</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">gupnp_control_point_callback_set</span><span style="color: #007700">(</span><span style="color: #0000BB">$cp</span><span style="color: #007700">, </span><span style="color: #0000BB">GUPNP_SIGNAL_SERVICE_PROXY_AVAILABLE</span><span style="color: #007700">, </span><span style="color: #0000BB">$cb</span><span style="color: #007700">, </span><span style="color: #0000BB">$arg</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Start for browsing */<br /></span><span style="color: #0000BB">gupnp_control_point_browse_start</span><span style="color: #007700">(</span><span style="color: #0000BB">$cp</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?></span> </span> </code></div> </div> </div> </p> </div><hr /><div class="manualnavbar" style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="gupnp.browsing.html">Browsing devices and services</a></div> <div class="next" style="text-align: right; float: right;"><a href="ref.gupnp.html">Gupnp Functions</a></div> <div class="up"><a href="gupnp.examples.html">Examples</a></div> <div class="home"><a href="index.html">PHP Manual</a></div> </div></body></html>