<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.innovaphone.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Peter.seyringer</id>
	<title>innovaphone wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.innovaphone.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Peter.seyringer"/>
	<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Special:Contributions/Peter.seyringer"/>
	<updated>2026-05-08T09:37:35Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto13r1:LDAP_IP_Phones_Directory_Services_via_Reverse_Proxy&amp;diff=55317</id>
		<title>Howto13r1:LDAP IP Phones Directory Services via Reverse Proxy</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto13r1:LDAP_IP_Phones_Directory_Services_via_Reverse_Proxy&amp;diff=55317"/>
		<updated>2020-02-13T20:23:00Z</updated>

		<summary type="html">&lt;p&gt;Peter.seyringer: /* Reverse Proxy manual modifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
This article is about How to enable LDAP search at innovaphone IP Phones via Reverse Proxy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Status per default after Install ==&lt;br /&gt;
Currently by default IP phones registered via Reverse Proxy are NOT able to search in the PBX users and in the external LDAP resource (for example the Contacts database)&lt;br /&gt;
To enable the LDAP search on the Phones we have to do some manual modification.&lt;br /&gt;
== Steps to do ==&lt;br /&gt;
&lt;br /&gt;
# Create an LDAP user in the PBX under services, LDAP&lt;br /&gt;
# Retrieve the Contacts App username and password.&lt;br /&gt;
# Modify the IP Phone or the Template used for the IP Phones that register via the Reverse Proxy.&lt;br /&gt;
# Modify the Reverse Proxy entries manual!&lt;br /&gt;
&lt;br /&gt;
=== Create a LDAP user ===&lt;br /&gt;
Steps to do: Under Services, LDAP, Server&lt;br /&gt;
&lt;br /&gt;
* 1. Create a ldapuser account under Services, LDAP, Server (for example pbx.system.com/ldap-guest)&lt;br /&gt;
* 2. Define a secret password and store it in a save place. You need it later on. And press OK to save. You can also use the same password as used in step B. because this is the same as used in the default ldap-guest&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:LDAPuser.png|LDAP user]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Find your Contacts ldap password ===&lt;br /&gt;
&lt;br /&gt;
Steps to do: In PBX manager, Plugin AP contacts.&lt;br /&gt;
&lt;br /&gt;
* 1. Click on AP contacts plugin and click in the right pane on configuration.&lt;br /&gt;
* 2. Check the Display Password(LDAP).&lt;br /&gt;
* 3. Copy the Password and store it for later use. This password is the same as used for the default ldap-guest&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:contacts ldap password.png|Plugin AP Contacts]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create Phone Template or change phone settings ===&lt;br /&gt;
&lt;br /&gt;
Steps to do: Under Phone, Directories or Template, config, Phone, Directories.&lt;br /&gt;
&lt;br /&gt;
* 1. Check Enable and Use TLS and change the PBX section server to pbx.system.com  (of course use your own pbx, domain and systemnames, pbx.yoursystemname.com 😉)&lt;br /&gt;
* 2. Port 636 for LDAPS&lt;br /&gt;
* 3. Username change it to pbx.system.com/ldapuser  (the user created in  section a.)&lt;br /&gt;
* 4. Enter the password off the ldapuser (created  in the section a.)&lt;br /&gt;
* 5. External LDAP Server, Check enable and Use TLS and enter the Servers dnsname apps.system.com&lt;br /&gt;
* 6. Port 636 for LDAPS&lt;br /&gt;
* 7. LDAP username which is the username contacts from the App contacts&lt;br /&gt;
* 8. The password, which is the password copied from the Plugin AP contacts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:LDAP phone or template OK.png|LDAP phone or template config]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you created a new template, make sure you assign this template to the appropriate users!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Reverse Proxy manual modifications ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the Reverse Proxy we have to do some manual changes.&lt;br /&gt;
(After these changes make a backup and DO NOT use the PBX manager plugin for the Reverse Proxy anymore. Otherwise your manual changes will be broken when saving via the RP plugin) &lt;br /&gt;
&lt;br /&gt;
This has to be verified because it seems to be OK in V13r1sr8&lt;br /&gt;
&lt;br /&gt;
In this example the Reverse Proxy runs on the PBX itself and listens to the standard default ports +10&lt;br /&gt;
Make sure that on your router/firewall the default ports will be redirected to these defaults ports +10&lt;br /&gt;
&lt;br /&gt;
Steps to do in the Reverse Proxy:&lt;br /&gt;
&lt;br /&gt;
* 1. Change the apps.system.com line and add LDAPS port 636 and redirect it to the IP address of the App Platform. This redirection is used for the external LDAP users search in the App Platform, Contacts database.&lt;br /&gt;
* 2. Change the line with pbx.system.com and add LDAPS port 636 and redirect it to the IP address of the PBX.  This redirection is used for the search internal LDAP database, PBX users.&lt;br /&gt;
* 3. Change the line with system.com add LDAPS port 636 and redirect it to the IP address of the App Platform (original: &amp;quot;PBX&amp;quot; but this is not correct). This redirection is used for the authentication and bind request to the Contacts App.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:ReverseProxy System OK.png|ReverseProxy config|1280px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When opening the Reverse Proxy via the PBXmanger Plugin it will be shown as in the following picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:ReverseProxy Plugin OK.png|ReverseProxy Plugin|1280px]]&lt;br /&gt;
&lt;br /&gt;
== Directory search on the IP phone  ==&lt;br /&gt;
&lt;br /&gt;
A directory search on the IP Phone should now result in a search within the PBX internal users and in the Contacts database with External Contacts.&lt;br /&gt;
&lt;br /&gt;
In example 1 a search is done to kpe which shows the results from the PBX (upper result) and the results from the Contacts (other lines) &lt;br /&gt;
&lt;br /&gt;
In example 2 the search is done to almost the complete name to show only the line from the external contacts.&lt;br /&gt;
&lt;br /&gt;
The examples shows you also how you can make a LCD dump of the Phone, this is also possible remotely via the Devices App, Admin UI of the Phone.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
example 1: [[Image:KPEresult.png|Directory Result KPE]]  example2: [[Image:KCresult.png|Directory Result KC]]&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
For Debugging if you get no search results, use Wireshark and trace for example on the IP Phone.&lt;br /&gt;
&lt;br /&gt;
Open the Phones Admin UI, Maintenance, Diagnostic, Tracing and tick the boxes All IPv4 TCP/UDP Traffic, All IPv4 TLS Traffic, Enable RPCAP.&lt;br /&gt;
&lt;br /&gt;
Open the Webpage of the IP Phone https://x.x.x.x/debug.xml and tick the checkbox, Directories.&lt;br /&gt;
&lt;br /&gt;
Start the wireshark trace and capture a Directory request from your IP Phone.  &lt;br /&gt;
&lt;br /&gt;
Filter the data with the filter: tcp.port==636 Find a packet containing the destination port 636 and right-click, choose decode-as and add the source and destination port to the ldap protocol.  &lt;br /&gt;
&lt;br /&gt;
Now you should be also able to filter also directly on the ldap protocol.&lt;br /&gt;
&lt;br /&gt;
An example of a succesfull LDAP request is shown in the picture below. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
example: [[Image:LDAPrequest.png|Directory request|1280px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
* [[Reference13r1:Concept_Number_Resolution_and_LDAP|Concept Number Resolution and LDAP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;/div&gt;</summary>
		<author><name>Peter.seyringer</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto:PHP_based_Update_Server&amp;diff=43880</id>
		<title>Howto:PHP based Update Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto:PHP_based_Update_Server&amp;diff=43880"/>
		<updated>2016-08-28T18:26:43Z</updated>

		<summary type="html">&lt;p&gt;Peter.seyringer: /* Cache */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Applies To==&lt;br /&gt;
This information applies to&lt;br /&gt;
&lt;br /&gt;
* all innovaphone devices&lt;br /&gt;
* web server running PHP 5 (e.g. Linux Application Platform)&lt;br /&gt;
&lt;br /&gt;
All Versions. &lt;br /&gt;
&lt;br /&gt;
By default, the [[Reference10:Concept_Update_Server | Update Server]] mechanism reads a file that corresponds to the device type (e.g. &amp;lt;code&amp;gt;update-ip222.htm&amp;lt;/code&amp;gt;).  While this makes sense (update scripts my vary by device type), it is sometimes tedious, as you have to edit a huge amount of files which typically are (at least partly) identical.&lt;br /&gt;
&lt;br /&gt;
Here is a PHP script that can be used as an &#039;&#039;Update Server&#039;&#039; that allows you to simplify the handling of update scripts. It also includes a mechanism that makes sure that all devices always have the same firmware installed as a given &#039;&#039;master device&#039;&#039; has.   Finally, it implements a straight forward configuration backup scheme.&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
The update server script requires a web server with working PHP 5.3 or higher platform.  It has been tested with Apache, IIS and ligHTTPD (on a [[Reference10:Concept Linux Application Platform | Linux Application Platform]]).   &lt;br /&gt;
&lt;br /&gt;
The platform running the PHP scripts must have a valid time setting!&lt;br /&gt;
&lt;br /&gt;
To use the backup function, the web server must be able to handle PUT requests using &#039;&#039;chunked encoding&#039;&#039;.  IIS is known to be &#039;&#039;not compatible&#039;&#039; with this requirement.  Running the backup code on an IIS requires a workaround on the IIS (see http://stackoverflow.com/questions/27451882/retrieving-chunked-put-data-with-php-on-iis-7-hung) and some changes in the &amp;lt;code&amp;gt;update.php&amp;lt;/code&amp;gt; code.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
The update server can&lt;br /&gt;
* update all your devices with boot code and firmware that corresponds to the versions running on a reference device of your choice&lt;br /&gt;
* save backups of your devices configuration. Backups are saved only if the configuration changed since the last backup&lt;br /&gt;
* invoke your own update scripts depending on &lt;br /&gt;
** various phases (e.g. you can have &#039;&#039;staging&#039;&#039; scripts which are only executed once and normal scripts which are executed in normal operation later on)&lt;br /&gt;
** devices classes (e.g. you can have different scripts for phones and gateways)&lt;br /&gt;
** environments (e.g. you can have scripts for your internal devices and others for devices in home offices)&lt;br /&gt;
&lt;br /&gt;
=== Installation ===&lt;br /&gt;
To install the tool&lt;br /&gt;
* create a new directory where your web server can run .php scripts&lt;br /&gt;
* copy the files &amp;lt;code&amp;gt;update.php&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;  and &amp;lt;code&amp;gt;config.dtd&amp;lt;/code&amp;gt; in to this directory&lt;br /&gt;
* create a directory named &amp;lt;code&amp;gt;cache&amp;lt;/code&amp;gt; in this directory&lt;br /&gt;
* create a directory named &amp;lt;code&amp;gt;backup&amp;lt;/code&amp;gt; in this directory&lt;br /&gt;
* make sure your web server can modify the two sub-directories&lt;br /&gt;
** on Linux, either change the directory modes to &amp;lt;code&amp;gt;0777&amp;lt;/code&amp;gt; or change the ownership of the directory to the web server user-id&lt;br /&gt;
** on Windows, grant &#039;&#039;modify&#039;&#039; rights to the web server user (usually something like &#039;&#039;IUSR_xyz&#039;&#039;) &lt;br /&gt;
* create a directory named &amp;lt;code&amp;gt;fw&amp;lt;/code&amp;gt; in this directory&lt;br /&gt;
* copy firmware and boot code files (such as &#039;&#039;ipxxx.bin&#039;&#039; and &#039;&#039;bootxxx.bin&#039;&#039;) to sub-directories of the &amp;lt;code&amp;gt;fw&amp;lt;/code&amp;gt; directory (so you have e.g. firmware build 12345 for the IP232 in &amp;lt;code&amp;gt;fw/12345/ip232.bin&amp;lt;/code&amp;gt;)&lt;br /&gt;
* configure your devices to use an update script (should be done &#039;&#039;after&#039;&#039; you have completed the configuration, see below)&lt;br /&gt;
** the &#039;&#039;Command File URL&#039;&#039; must be &amp;lt;code&amp;gt;http://&amp;lt;/code&amp;gt;&#039;&#039;url-to-your-new-directory&#039;&#039;&amp;lt;code&amp;gt;/update.php?type=#t&amp;lt;/code&amp;gt; (of course, https will work too)&lt;br /&gt;
** the &#039;&#039;Interval [min]&#039;&#039; can be set to any reasonable value.  We do not recommend too large values to make sure, update script changes propagate soon through your network&lt;br /&gt;
** you will usually do this using DHCP (see &#039;&#039;Update URL&#039;&#039; and &#039;&#039;Update Poll Interval&#039;&#039; in [[Reference12r1:DHCP_client]])&lt;br /&gt;
&lt;br /&gt;
==== On the Linux Application Platform ====&lt;br /&gt;
&lt;br /&gt;
On the &#039;&#039;Linux Application Platform&#039;&#039;, you would &lt;br /&gt;
* open the LAP&#039;s file system using a SFTP client such as e.g. WinSCP (if you have not yet changed it, the default credentials will be &amp;lt;code&amp;gt;admin/linux&amp;lt;/code&amp;gt;, see [[Reference10:Concept_Linux_Application_Platform#Default_Credentials | Concept Linux Application Platform]]). Note that you must use SFTP rather than WebDAV, as WebDAV will not give access to the executable web server files&lt;br /&gt;
** create the new directory called &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; underneath the &amp;lt;code&amp;gt;/var/www/innovaphone&amp;lt;/code&amp;gt; directory. The URL to reach the update script will be &amp;lt;code&amp;gt;http://&amp;lt;/code&amp;gt;&#039;&#039;your-lap&#039;&#039;&amp;lt;code&amp;gt;/update/update.php&amp;lt;/code&amp;gt;&lt;br /&gt;
** copy the update server files (&amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;update.php&amp;lt;/code&amp;gt; etc.) in to this directory&lt;br /&gt;
** create sub-directories &amp;lt;code&amp;gt;backup&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cache&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fw&amp;lt;/code&amp;gt;&lt;br /&gt;
* log in to the LAP&#039;s admin UI (if you have not yet changed it, the default credentials will be &amp;lt;code&amp;gt;admin/linux&amp;lt;/code&amp;gt;, see [[Reference10:Concept_Linux_Application_Platform#Default_Credentials | Concept Linux Application Platform]])&lt;br /&gt;
** go to &#039;&#039;Administration/WebServer/Change web server properties and public access to the web/webdav&#039;&#039;&lt;br /&gt;
** add &amp;lt;code&amp;gt;/update/&amp;lt;/code&amp;gt; to &#039;&#039;Public Web Paths&#039;&#039;&lt;br /&gt;
* log in the LAP&#039;s root shell (using e.g. putty, if you have not yet changed it, the default credentials will be &amp;lt;code&amp;gt;root/iplinux&amp;lt;/code&amp;gt;, see [[Reference10:Concept_Linux_Application_Platform#Default_Credentials | Concept Linux Application Platform]])&lt;br /&gt;
** &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;/var/www/innovaphone&amp;lt;/code&amp;gt;&lt;br /&gt;
** change owner of &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; and all its sub -directories to &amp;lt;code&amp;gt;www-data&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;chown -R www-data update&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
===Configuration===&lt;br /&gt;
==== Basic Parameters ====&lt;br /&gt;
All tweakable parameters are present in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.  You should start with just setting the &#039;&#039;info&#039;&#039; attribute of the &#039;&#039;master&#039;&#039; tag and leave everything else &#039;&#039;as is&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The following tags are available:&lt;br /&gt;
&lt;br /&gt;
===== master =====&lt;br /&gt;
Defines the reference device where the firmware and boot code information is taken from.&lt;br /&gt;
; info : the URL to the device info data.  Set it to an URL like &amp;lt;code&amp;gt;http://&amp;lt;/code&amp;gt;&#039;&#039;your-reference-device&#039;&#039;&amp;lt;code&amp;gt;/CMD0/box_info.xml&amp;lt;/code&amp;gt;. Please note that this device must not have the &#039;&#039;Password protect all HTTP pages&#039;&#039; set in &#039;&#039;Services/HTTP/Server&#039;&#039;. &lt;br /&gt;
; expire : the firmware info cache lifetime.  The firmware information is cached in a file (to make sure this information is present even if the reference device is offline)&lt;br /&gt;
; cache : the cache file name.  The web server must be able to write this file (see [[#Installation | &#039;&#039;Installation&#039;&#039; ]] above)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;master &lt;br /&gt;
        info=&amp;quot;http://172.16.0.10/CMD0/box_info.xml&amp;quot;&lt;br /&gt;
        expire=&amp;quot;3600&amp;quot;&lt;br /&gt;
        cache=&amp;quot;cache/master-info.xml&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== fwstorage =====&lt;br /&gt;
Defines from where the device will retrieve the firmware files for updates.&lt;br /&gt;
; url : defines the URL to retrieve the files from.  The requested firmware/boot-code build number will be appended followed by a trailing slash (&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;).  The file system the URL points to must therefore contain sub-directories for each firmware build which contain the corresponding firmware builds (e.g, &#039;&#039;fw/12345/ip232.bin&#039;&#039;).  If &#039;&#039;url&#039;&#039; is not an URL (as is the case for the default value &amp;lt;code&amp;gt;fw&amp;lt;/code&amp;gt;), it is treated as a sub-directory underneath the script directory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;fwstorage url=&amp;quot;fw&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== backup =====&lt;br /&gt;
Defines where backup files are kept.&lt;br /&gt;
; dir : the directory underneath the script directory where backups are stored&lt;br /&gt;
; nbackups : the number of different backup files kept&lt;br /&gt;
; scfg : the target URL for the scfg command.  If this is not an url, it is interpreted relative to the script directory URL. You can add more options for the &#039;&#039;scfg&#039;&#039; command, like in &amp;lt;code&amp;gt;scfg=&amp;quot;update.php?mode=backup&amp;amp;amp;hwid=#h ser hourly /force 1&amp;quot;&amp;lt;/code&amp;gt; (this example will make sure backups are attempted only once per hour, so as to reduce load on the server).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;backup &lt;br /&gt;
        dir=&amp;quot;backup&amp;quot;&lt;br /&gt;
        nbackups=&amp;quot;10&amp;quot;&lt;br /&gt;
        scfg=&amp;quot;update.php?mode=backup&amp;amp;amp;hwid=#h &amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== times =====&lt;br /&gt;
Defines the arguments of the [[Reference10:Concept_Update_Server#Times_command | times command]].  If neither &#039;&#039;allow&#039;&#039; nor &#039;&#039;initial&#039;&#039; is set, no &#039;&#039;times&#039;&#039; command is used (that is, the update scripts will be processed at all times).&lt;br /&gt;
; allow : the hours to be used in the &#039;&#039;times&#039;&#039; command&lt;br /&gt;
; initial : the minutes to be used in the &#039;&#039;times&#039;&#039; command&lt;br /&gt;
; check : if set to true, update scripts will be executed once only (unless their contents change). In this case, the devices will be executed again when you have edited/changed them&lt;br /&gt;
; polling : when you are using multiple &#039;&#039;phases&#039;&#039; (e.g. &#039;&#039;staging&#039;&#039; and &#039;&#039;update&#039;&#039;), this defines the number of seconds to wait before the device reads the scripts for the next phase (see [[Reference10:Concept_Update_Server#Provision_command | provision command]])&lt;br /&gt;
; interval : polling interval in minutes for normal operation (that is, when all staging s done)&lt;br /&gt;
; grace : defines the number of seconds that must expire before update script changes take effect.  If &#039;&#039;grace&#039;&#039; is set to 900, then update scripts will not be executed until 15 minutes (900/60) have expired since the last edit of a script that normally would be executed for the calling device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;times &lt;br /&gt;
        allow=&amp;quot;22,23,0,1,2,3,4&amp;quot; &lt;br /&gt;
        initial=&amp;quot;1&amp;quot;&lt;br /&gt;
        check=&amp;quot;true&amp;quot;&lt;br /&gt;
        polling=&amp;quot;5&amp;quot;&lt;br /&gt;
        interval=&amp;quot;15&amp;quot;&lt;br /&gt;
        grace=&amp;quot;900&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== phases ===== &lt;br /&gt;
Defines the scripting phases.  In many installations, there are initializations which should be performed once only.  This is known as the &#039;&#039;staging&#039;&#039; phase.  Once this is done, the devices continue with the execution of the normal update scripts (this phase is known as &#039;&#039;update&#039;&#039; by default).  In the (unlikely) event that you want more or less phases, you can add/remove &#039;&#039;phase&#039;&#039; tags.&lt;br /&gt;
====== phase ====== &lt;br /&gt;
; id : the name for the phase&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;phases&amp;gt;&lt;br /&gt;
        &amp;lt;!-- sequence is important! --&amp;gt;&lt;br /&gt;
        &amp;lt;phase id=&amp;quot;staging&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;phase id=&amp;quot;update&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/phases&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== environments =====&lt;br /&gt;
Defines the distinguished environments.  Devices can have zero or more &#039;&#039;environments&#039;&#039; associated.  The environments a device is considered to be in must be passed as &amp;lt;code&amp;gt;?env=&amp;lt;/code&amp;gt;&#039;&#039;name1,name2,..&#039;&#039; URL query arg in the update url.  Update scripts for all environments listed will be applied. The default config file defines the environments &#039;&#039;intern&#039;&#039; and &#039;&#039;homeoffice&#039;&#039; but you can define your own if you like.&lt;br /&gt;
====== environment ====== &lt;br /&gt;
Each &#039;&#039;environment&#039;&#039; may have a number of sub-tags of type &#039;&#039;implies&#039;&#039;. It contains the &#039;&#039;id&#039;&#039; of another &#039;&#039;environment&#039;&#039;.   If a device is in an environment with an &#039;&#039;implies&#039;&#039; sub-tag, it is assumed that it is in the implied environment also. &lt;br /&gt;
; id : the name for the environment&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;environments&amp;gt;&lt;br /&gt;
        &amp;lt;environment id=&#039;hq&#039;&amp;gt;&lt;br /&gt;
            &amp;lt;implies&amp;gt;intranet&amp;lt;/implies&amp;gt;&lt;br /&gt;
        &amp;lt;/environment&amp;gt;&lt;br /&gt;
        &amp;lt;environment id=&#039;intranet&#039;/&amp;gt;&lt;br /&gt;
        &amp;lt;environment id=&#039;homeoffice&#039;/&amp;gt;&lt;br /&gt;
    &amp;lt;/environments&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== classes =====&lt;br /&gt;
Defines the available device classes.  Devices of different classes (e.g. phones and gateways) can have different update scripts. The device class is derived from the &amp;lt;code&amp;gt;#t&amp;lt;/code&amp;gt; (device type) query arg of the update script URL (which is why you must configure it in the update URL, see above).  By default, the classes &#039;&#039;phone&#039;&#039; and &#039;&#039;gw&#039;&#039; are recognized. A given device can be in multiple classes and will execute all update scripts available for these classes. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;classes&amp;gt;&lt;br /&gt;
        &amp;lt;class id=&amp;quot;gw&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;model&amp;gt;ip0010&amp;lt;/model&amp;gt;&lt;br /&gt;
            ...&lt;br /&gt;
        &amp;lt;/class&amp;gt;&lt;br /&gt;
        &amp;lt;class id=&amp;quot;phone&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;model&amp;gt;ip110&amp;lt;/model&amp;gt;&lt;br /&gt;
            ...&lt;br /&gt;
        &amp;lt;/class&amp;gt;&lt;br /&gt;
    &amp;lt;/classes&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====== class ======&lt;br /&gt;
Each &#039;&#039;class&#039;&#039; has a number of sub-tags of type &#039;&#039;model&#039;&#039;. It contains the value replaced for the &amp;lt;code&amp;gt;#t&amp;lt;/code&amp;gt; query arg.&lt;br /&gt;
; id : the name of the class&lt;br /&gt;
&lt;br /&gt;
===== stdargs =====&lt;br /&gt;
Better don&#039;t touch :-)&lt;br /&gt;
&lt;br /&gt;
===Testing===&lt;br /&gt;
To test your installation, you can simply use your browser simulating your device (it is convenient to use your browsers &#039;&#039;view source&#039;&#039; function to inspect the result). &lt;br /&gt;
&lt;br /&gt;
==== Cache ====&lt;br /&gt;
Open the update URL with the &amp;lt;code&amp;gt;#t&amp;lt;/code&amp;gt; argument replaced by the simulated device type (e.g. &amp;lt;code&amp;gt;http://172.16.10.65/update/update.php?type=ip222&amp;lt;/code&amp;gt;).  You will see an update script.  The first line will look like &lt;br /&gt;
 # failed to use cached data (cache not current), retrieving info online&lt;br /&gt;
 # phase: ...&lt;br /&gt;
This is normal, as there is no cache yet.  Now simply open the URL again (by hitting F5 e.g.).  You will now see &lt;br /&gt;
 # firmware build info cache is current&lt;br /&gt;
If so, your firmware info retrieval and your cache works.&lt;br /&gt;
&lt;br /&gt;
if not, there is something wrong with your master/info URL or your web server has no write access to the &amp;lt;code&amp;gt;cache&amp;lt;/code&amp;gt; sub-directory.&lt;br /&gt;
&lt;br /&gt;
==== Update Scripts ====&lt;br /&gt;
You should now see a line like &lt;br /&gt;
 # phase: staging, nextphase: update, environment: intern, type: ip222, classes: phone&lt;br /&gt;
in the update script.  This shows that the scripts for the first phasem &#039;&#039;staging&#039;&#039;, the default (i.e. first) environment &#039;&#039;intern&#039;&#039; and for devices of class &#039;&#039;phone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The next lines will list the potential update scripts for this situation:&lt;br /&gt;
&lt;br /&gt;
 # possible files (from C:\sources\wiki-src\sample\php-update-server\sample\sources):&lt;br /&gt;
 # staging-phone-intern.txt (does not exist)&lt;br /&gt;
 # staging-phone-all.txt (does not exist)&lt;br /&gt;
 # staging-all-intern.txt (does not exist)&lt;br /&gt;
 # staging-all-all.txt (does not exist)&lt;br /&gt;
 # all-phone-intern.txt (does not exist)&lt;br /&gt;
 # all-phone-all.txt (does not exist)&lt;br /&gt;
 # all-all-intern.txt (does not exist)&lt;br /&gt;
 # all-all-all.txt (does not exist)&lt;br /&gt;
&lt;br /&gt;
Of course, as you have no scripts yet, all options are tagged as &#039;&#039;(does not exist)&#039;&#039;.  If one or more of such scripts exist, they will be executed in the order listed. &lt;br /&gt;
&lt;br /&gt;
==== Backup ====&lt;br /&gt;
&lt;br /&gt;
The next lines show you where the device backup will be sent to:&lt;br /&gt;
&lt;br /&gt;
 # backup&lt;br /&gt;
 mod cmd UP0 scfg http://172.16.10.65/update.php?mode=backup&amp;amp;hwid=#h ser hourly /force 1&lt;br /&gt;
&lt;br /&gt;
You can see that the backups are sent every hour (&#039;&#039;/force 1&#039;&#039;) if this has been configured in the &amp;lt;code&amp;gt;backup&amp;lt;/code&amp;gt; tag (see above).&lt;br /&gt;
&lt;br /&gt;
==== Firmware ====&lt;br /&gt;
The next block shows the required update of the firmware or boot code:&lt;br /&gt;
&lt;br /&gt;
 # current firmware (unknown) does not match required firmware (120663)&lt;br /&gt;
 mod cmd UP0 prot http://172.16.10.65/fw/120663/ ser 120663&lt;br /&gt;
 # current boot code (unknown) does not match required boot code (120502)&lt;br /&gt;
 mod cmd UP0 boot http://172.16.10.65/fw/120502/ ser 120502&lt;br /&gt;
 # make sure remaining update scripts are executed with up-to-date firmware&lt;br /&gt;
 iresetn&lt;br /&gt;
&lt;br /&gt;
In this example, the reference device is running firmware build 120663 and boot code build 120502.  The update server does not know the devices current firmware, so it creates an update command for both.  You can now add a &amp;lt;code&amp;gt;&amp;amp;PROT=120663&amp;lt;/code&amp;gt; query arg to the URL.  This tells the update server the firmware your device is running (a real life device will include this argument automatically, so there is no need to configure it anywhere).  When you retrieve the script again, no update command for the firmware will be included:&lt;br /&gt;
&lt;br /&gt;
 # current boot code (unknown) does not match required boot code (120502)&lt;br /&gt;
 mod cmd UP0 boot http://172.16.10.65/fw/120502/ ser 120502&lt;br /&gt;
 # make sure remaining update scripts are executed with up-to-date firmware&lt;br /&gt;
 iresetn&lt;br /&gt;
&lt;br /&gt;
==== Next Phase Switching ====&lt;br /&gt;
As you have 2 phases defined in your config file, the script will instruct the device to switch to the next phase (&#039;&#039;update&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 # warping from &#039;staging&#039; to &#039;update&#039; (url=http://172.16.10.65/update.php?type=#t&amp;amp;phase=update)&lt;br /&gt;
 config add UP1 /url http%3A%2F%2F172.16.10.65%2Fupdate.php%3Ftype%3D%2523t%26phase%3Dupdate&lt;br /&gt;
 config add UP1 /no-dhcp&lt;br /&gt;
 config write&lt;br /&gt;
 config activate&lt;br /&gt;
 &lt;br /&gt;
 # turn on fast polling&lt;br /&gt;
 mod cmd UP1 provision 5&lt;br /&gt;
&lt;br /&gt;
This is done by re-writing the update URL in the client.  You can simulate this by adding the &amp;lt;code&amp;gt;&amp;amp;phase=update&amp;lt;/code&amp;gt; query argument to your browser URL. You will see then: &lt;br /&gt;
&lt;br /&gt;
 # &#039;update&#039; is last phase&lt;br /&gt;
&lt;br /&gt;
==== Config File Re-Execution ====&lt;br /&gt;
In the last (that is, standard) phase, the config files will be executed only when changed.  This done using a [[Reference10:Concept_Update_Server#Check_command | check command ]]:&lt;br /&gt;
&lt;br /&gt;
 # skip remainder if there were no changes in config files&lt;br /&gt;
 mod cmd UP1 check ser d41d8cd98f00b204e9800998ecf8427e&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;serial&#039;&#039; &amp;lt;code&amp;gt;d41d8cd98f00b204e9800998ecf8427e&amp;lt;/code&amp;gt; is a hash code computed from the content of all script files that are valid for the calling device.  We can see how this works when we create an update script that is valid for the device.  You create a file called &amp;lt;code&amp;gt;all-all-all.txt&amp;lt;/code&amp;gt; in the update server directory and place something (e.g. a comment in it):&lt;br /&gt;
&lt;br /&gt;
You will now see that the script retrieved changes:&lt;br /&gt;
&lt;br /&gt;
 # skip remainder if there were no changes in config files&lt;br /&gt;
 mod cmd UP1 check ser 1e906fd3737281ebd4edbdf60a196fb3&lt;br /&gt;
 &lt;br /&gt;
 # 1 config files follow:&lt;br /&gt;
 # { begin script &#039;all-all-all.txt&#039; &lt;br /&gt;
 # my first update script&lt;br /&gt;
 &lt;br /&gt;
 # end script &#039;all-all-all.txt&#039; }&lt;br /&gt;
&lt;br /&gt;
The new &#039;&#039;serial&#039;&#039; &amp;lt;code&amp;gt;1e906fd3737281ebd4edbdf60a196fb3&amp;lt;/code&amp;gt; differs from the previous one. As a result, the devices will execute their update scripts whenever they change.&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
To debug update script execution in your real devices, you can &lt;br /&gt;
&lt;br /&gt;
* open the devices &amp;lt;code&amp;gt;debug.xml&amp;lt;/code&amp;gt; page (e.g. http://x.x.x.x/debug.xml)&lt;br /&gt;
* check the &#039;&#039;Update/Polling&#039;&#039;, &#039;&#039;Update/Execution&#039;&#039;, &#039;&#039;HTTP/Client&#039;&#039; and &#039;&#039;HTTP/verbose&#039;&#039; check marks&lt;br /&gt;
* force the update client in the device to run using the &amp;lt;code&amp;gt;mod cmd UP1 poll&amp;lt;/code&amp;gt; command (e.g. &amp;lt;code&amp;gt;http://x.x.x.x/!mod cmd UP1 poll&amp;lt;/code&amp;gt;)&lt;br /&gt;
* look at the traces (best with wireshark)&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
You can easily see the current status of your update server and scripts by calling the URL &amp;lt;code&amp;gt;http://&amp;lt;/code&amp;gt;&#039;&#039;your-update-server&#039;&#039;&amp;lt;code&amp;gt;/update.php?show&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Your own Update Scripts===&lt;br /&gt;
As you have seen, the update server will do some meaningful things (updating the device firmware and creating backups) even with no user supplied update scripts at all.  &lt;br /&gt;
&lt;br /&gt;
Feel free now to add your own update scripts.  All update script names must have the form &#039;&#039;phase&#039;&#039;&amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&#039;&#039;class&#039;&#039;&amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&#039;&#039;environment&#039;&#039;&amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; (e.g. update-phone-intern.txt). If the word &amp;lt;code&amp;gt;all&amp;lt;/code&amp;gt; is used for any of the components, the file is executed for all phases, classes or environments respectively.&lt;br /&gt;
&lt;br /&gt;
When you retrieve the update script URL manually (e.g. using your browser), it will list all the potential update script files:&lt;br /&gt;
&lt;br /&gt;
 # possible files (from C:\sources\wiki-src\sample\php-update-server\sample\sources):&lt;br /&gt;
 # staging-phone-intern.txt (does not exist)&lt;br /&gt;
 # staging-phone-all.txt (does not exist)&lt;br /&gt;
 # staging-all-intern.txt (does not exist)&lt;br /&gt;
 # staging-all-all.txt (does not exist)&lt;br /&gt;
 # all-phone-intern.txt (does not exist)&lt;br /&gt;
 # all-phone-all.txt (does not exist)&lt;br /&gt;
 # all-all-intern.txt (does not exist)&lt;br /&gt;
 # all-all-all.txt (does not exist)&lt;br /&gt;
&lt;br /&gt;
Note that this list depends on &lt;br /&gt;
* the device&#039;s &#039;&#039;class&#039;&#039; (inferred from the &amp;lt;code&amp;gt;?type=#t&amp;lt;/code&amp;gt; query arg in the update URL)&lt;br /&gt;
* the device&#039;s &#039;&#039;environment&#039;&#039; (as specified by the optional &amp;lt;code&amp;gt;&amp;amp;env=&amp;lt;/code&amp;gt;&#039;&#039;environment-name&#039;&#039; query arg in the update URL)&lt;br /&gt;
&lt;br /&gt;
== Download ==&lt;br /&gt;
*[http://download.innovaphone.com/ice/wiki-src#php-update-server http://download.innovaphone.com/ice/wiki-src/] - download the complete file package of scripts and files described in this article&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [[Reference10:Concept_Update_Server]]&lt;br /&gt;
* [[Reference12r1:DHCP_client]]&lt;br /&gt;
* [[Reference10:Concept_Linux_Application_Platform]]&lt;br /&gt;
* [[Reference10:Concept_Provisioning]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Sample|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Peter.seyringer</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto:PHP_based_Update_Server&amp;diff=43879</id>
		<title>Howto:PHP based Update Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto:PHP_based_Update_Server&amp;diff=43879"/>
		<updated>2016-08-28T18:24:33Z</updated>

		<summary type="html">&lt;p&gt;Peter.seyringer: /* On the Linux Application Platform */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Applies To==&lt;br /&gt;
This information applies to&lt;br /&gt;
&lt;br /&gt;
* all innovaphone devices&lt;br /&gt;
* web server running PHP 5 (e.g. Linux Application Platform)&lt;br /&gt;
&lt;br /&gt;
All Versions. &lt;br /&gt;
&lt;br /&gt;
By default, the [[Reference10:Concept_Update_Server | Update Server]] mechanism reads a file that corresponds to the device type (e.g. &amp;lt;code&amp;gt;update-ip222.htm&amp;lt;/code&amp;gt;).  While this makes sense (update scripts my vary by device type), it is sometimes tedious, as you have to edit a huge amount of files which typically are (at least partly) identical.&lt;br /&gt;
&lt;br /&gt;
Here is a PHP script that can be used as an &#039;&#039;Update Server&#039;&#039; that allows you to simplify the handling of update scripts. It also includes a mechanism that makes sure that all devices always have the same firmware installed as a given &#039;&#039;master device&#039;&#039; has.   Finally, it implements a straight forward configuration backup scheme.&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
The update server script requires a web server with working PHP 5.3 or higher platform.  It has been tested with Apache, IIS and ligHTTPD (on a [[Reference10:Concept Linux Application Platform | Linux Application Platform]]).   &lt;br /&gt;
&lt;br /&gt;
The platform running the PHP scripts must have a valid time setting!&lt;br /&gt;
&lt;br /&gt;
To use the backup function, the web server must be able to handle PUT requests using &#039;&#039;chunked encoding&#039;&#039;.  IIS is known to be &#039;&#039;not compatible&#039;&#039; with this requirement.  Running the backup code on an IIS requires a workaround on the IIS (see http://stackoverflow.com/questions/27451882/retrieving-chunked-put-data-with-php-on-iis-7-hung) and some changes in the &amp;lt;code&amp;gt;update.php&amp;lt;/code&amp;gt; code.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
The update server can&lt;br /&gt;
* update all your devices with boot code and firmware that corresponds to the versions running on a reference device of your choice&lt;br /&gt;
* save backups of your devices configuration. Backups are saved only if the configuration changed since the last backup&lt;br /&gt;
* invoke your own update scripts depending on &lt;br /&gt;
** various phases (e.g. you can have &#039;&#039;staging&#039;&#039; scripts which are only executed once and normal scripts which are executed in normal operation later on)&lt;br /&gt;
** devices classes (e.g. you can have different scripts for phones and gateways)&lt;br /&gt;
** environments (e.g. you can have scripts for your internal devices and others for devices in home offices)&lt;br /&gt;
&lt;br /&gt;
=== Installation ===&lt;br /&gt;
To install the tool&lt;br /&gt;
* create a new directory where your web server can run .php scripts&lt;br /&gt;
* copy the files &amp;lt;code&amp;gt;update.php&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;  and &amp;lt;code&amp;gt;config.dtd&amp;lt;/code&amp;gt; in to this directory&lt;br /&gt;
* create a directory named &amp;lt;code&amp;gt;cache&amp;lt;/code&amp;gt; in this directory&lt;br /&gt;
* create a directory named &amp;lt;code&amp;gt;backup&amp;lt;/code&amp;gt; in this directory&lt;br /&gt;
* make sure your web server can modify the two sub-directories&lt;br /&gt;
** on Linux, either change the directory modes to &amp;lt;code&amp;gt;0777&amp;lt;/code&amp;gt; or change the ownership of the directory to the web server user-id&lt;br /&gt;
** on Windows, grant &#039;&#039;modify&#039;&#039; rights to the web server user (usually something like &#039;&#039;IUSR_xyz&#039;&#039;) &lt;br /&gt;
* create a directory named &amp;lt;code&amp;gt;fw&amp;lt;/code&amp;gt; in this directory&lt;br /&gt;
* copy firmware and boot code files (such as &#039;&#039;ipxxx.bin&#039;&#039; and &#039;&#039;bootxxx.bin&#039;&#039;) to sub-directories of the &amp;lt;code&amp;gt;fw&amp;lt;/code&amp;gt; directory (so you have e.g. firmware build 12345 for the IP232 in &amp;lt;code&amp;gt;fw/12345/ip232.bin&amp;lt;/code&amp;gt;)&lt;br /&gt;
* configure your devices to use an update script (should be done &#039;&#039;after&#039;&#039; you have completed the configuration, see below)&lt;br /&gt;
** the &#039;&#039;Command File URL&#039;&#039; must be &amp;lt;code&amp;gt;http://&amp;lt;/code&amp;gt;&#039;&#039;url-to-your-new-directory&#039;&#039;&amp;lt;code&amp;gt;/update.php?type=#t&amp;lt;/code&amp;gt; (of course, https will work too)&lt;br /&gt;
** the &#039;&#039;Interval [min]&#039;&#039; can be set to any reasonable value.  We do not recommend too large values to make sure, update script changes propagate soon through your network&lt;br /&gt;
** you will usually do this using DHCP (see &#039;&#039;Update URL&#039;&#039; and &#039;&#039;Update Poll Interval&#039;&#039; in [[Reference12r1:DHCP_client]])&lt;br /&gt;
&lt;br /&gt;
==== On the Linux Application Platform ====&lt;br /&gt;
&lt;br /&gt;
On the &#039;&#039;Linux Application Platform&#039;&#039;, you would &lt;br /&gt;
* open the LAP&#039;s file system using a SFTP client such as e.g. WinSCP (if you have not yet changed it, the default credentials will be &amp;lt;code&amp;gt;admin/linux&amp;lt;/code&amp;gt;, see [[Reference10:Concept_Linux_Application_Platform#Default_Credentials | Concept Linux Application Platform]]). Note that you must use SFTP rather than WebDAV, as WebDAV will not give access to the executable web server files&lt;br /&gt;
** create the new directory called &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; underneath the &amp;lt;code&amp;gt;/var/www/innovaphone&amp;lt;/code&amp;gt; directory. The URL to reach the update script will be &amp;lt;code&amp;gt;http://&amp;lt;/code&amp;gt;&#039;&#039;your-lap&#039;&#039;&amp;lt;code&amp;gt;/update/update.php&amp;lt;/code&amp;gt;&lt;br /&gt;
** copy the update server files (&amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;update.php&amp;lt;/code&amp;gt; etc.) in to this directory&lt;br /&gt;
** create sub-directories &amp;lt;code&amp;gt;backup&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cache&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fw&amp;lt;/code&amp;gt;&lt;br /&gt;
* log in to the LAP&#039;s admin UI (if you have not yet changed it, the default credentials will be &amp;lt;code&amp;gt;admin/linux&amp;lt;/code&amp;gt;, see [[Reference10:Concept_Linux_Application_Platform#Default_Credentials | Concept Linux Application Platform]])&lt;br /&gt;
** go to &#039;&#039;Administration/WebServer/Change web server properties and public access to the web/webdav&#039;&#039;&lt;br /&gt;
** add &amp;lt;code&amp;gt;/update/&amp;lt;/code&amp;gt; to &#039;&#039;Public Web Paths&#039;&#039;&lt;br /&gt;
* log in the LAP&#039;s root shell (using e.g. putty, if you have not yet changed it, the default credentials will be &amp;lt;code&amp;gt;root/iplinux&amp;lt;/code&amp;gt;, see [[Reference10:Concept_Linux_Application_Platform#Default_Credentials | Concept Linux Application Platform]])&lt;br /&gt;
** &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;/var/www/innovaphone&amp;lt;/code&amp;gt;&lt;br /&gt;
** change owner of &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; and all its sub -directories to &amp;lt;code&amp;gt;www-data&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;chown -R www-data update&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
===Configuration===&lt;br /&gt;
==== Basic Parameters ====&lt;br /&gt;
All tweakable parameters are present in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;.  You should start with just setting the &#039;&#039;info&#039;&#039; attribute of the &#039;&#039;master&#039;&#039; tag and leave everything else &#039;&#039;as is&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The following tags are available:&lt;br /&gt;
&lt;br /&gt;
===== master =====&lt;br /&gt;
Defines the reference device where the firmware and boot code information is taken from.&lt;br /&gt;
; info : the URL to the device info data.  Set it to an URL like &amp;lt;code&amp;gt;http://&amp;lt;/code&amp;gt;&#039;&#039;your-reference-device&#039;&#039;&amp;lt;code&amp;gt;/CMD0/box_info.xml&amp;lt;/code&amp;gt;. Please note that this device must not have the &#039;&#039;Password protect all HTTP pages&#039;&#039; set in &#039;&#039;Services/HTTP/Server&#039;&#039;. &lt;br /&gt;
; expire : the firmware info cache lifetime.  The firmware information is cached in a file (to make sure this information is present even if the reference device is offline)&lt;br /&gt;
; cache : the cache file name.  The web server must be able to write this file (see [[#Installation | &#039;&#039;Installation&#039;&#039; ]] above)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;master &lt;br /&gt;
        info=&amp;quot;http://172.16.0.10/CMD0/box_info.xml&amp;quot;&lt;br /&gt;
        expire=&amp;quot;3600&amp;quot;&lt;br /&gt;
        cache=&amp;quot;cache/master-info.xml&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== fwstorage =====&lt;br /&gt;
Defines from where the device will retrieve the firmware files for updates.&lt;br /&gt;
; url : defines the URL to retrieve the files from.  The requested firmware/boot-code build number will be appended followed by a trailing slash (&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;).  The file system the URL points to must therefore contain sub-directories for each firmware build which contain the corresponding firmware builds (e.g, &#039;&#039;fw/12345/ip232.bin&#039;&#039;).  If &#039;&#039;url&#039;&#039; is not an URL (as is the case for the default value &amp;lt;code&amp;gt;fw&amp;lt;/code&amp;gt;), it is treated as a sub-directory underneath the script directory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;fwstorage url=&amp;quot;fw&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== backup =====&lt;br /&gt;
Defines where backup files are kept.&lt;br /&gt;
; dir : the directory underneath the script directory where backups are stored&lt;br /&gt;
; nbackups : the number of different backup files kept&lt;br /&gt;
; scfg : the target URL for the scfg command.  If this is not an url, it is interpreted relative to the script directory URL. You can add more options for the &#039;&#039;scfg&#039;&#039; command, like in &amp;lt;code&amp;gt;scfg=&amp;quot;update.php?mode=backup&amp;amp;amp;hwid=#h ser hourly /force 1&amp;quot;&amp;lt;/code&amp;gt; (this example will make sure backups are attempted only once per hour, so as to reduce load on the server).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;backup &lt;br /&gt;
        dir=&amp;quot;backup&amp;quot;&lt;br /&gt;
        nbackups=&amp;quot;10&amp;quot;&lt;br /&gt;
        scfg=&amp;quot;update.php?mode=backup&amp;amp;amp;hwid=#h &amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== times =====&lt;br /&gt;
Defines the arguments of the [[Reference10:Concept_Update_Server#Times_command | times command]].  If neither &#039;&#039;allow&#039;&#039; nor &#039;&#039;initial&#039;&#039; is set, no &#039;&#039;times&#039;&#039; command is used (that is, the update scripts will be processed at all times).&lt;br /&gt;
; allow : the hours to be used in the &#039;&#039;times&#039;&#039; command&lt;br /&gt;
; initial : the minutes to be used in the &#039;&#039;times&#039;&#039; command&lt;br /&gt;
; check : if set to true, update scripts will be executed once only (unless their contents change). In this case, the devices will be executed again when you have edited/changed them&lt;br /&gt;
; polling : when you are using multiple &#039;&#039;phases&#039;&#039; (e.g. &#039;&#039;staging&#039;&#039; and &#039;&#039;update&#039;&#039;), this defines the number of seconds to wait before the device reads the scripts for the next phase (see [[Reference10:Concept_Update_Server#Provision_command | provision command]])&lt;br /&gt;
; interval : polling interval in minutes for normal operation (that is, when all staging s done)&lt;br /&gt;
; grace : defines the number of seconds that must expire before update script changes take effect.  If &#039;&#039;grace&#039;&#039; is set to 900, then update scripts will not be executed until 15 minutes (900/60) have expired since the last edit of a script that normally would be executed for the calling device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;times &lt;br /&gt;
        allow=&amp;quot;22,23,0,1,2,3,4&amp;quot; &lt;br /&gt;
        initial=&amp;quot;1&amp;quot;&lt;br /&gt;
        check=&amp;quot;true&amp;quot;&lt;br /&gt;
        polling=&amp;quot;5&amp;quot;&lt;br /&gt;
        interval=&amp;quot;15&amp;quot;&lt;br /&gt;
        grace=&amp;quot;900&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== phases ===== &lt;br /&gt;
Defines the scripting phases.  In many installations, there are initializations which should be performed once only.  This is known as the &#039;&#039;staging&#039;&#039; phase.  Once this is done, the devices continue with the execution of the normal update scripts (this phase is known as &#039;&#039;update&#039;&#039; by default).  In the (unlikely) event that you want more or less phases, you can add/remove &#039;&#039;phase&#039;&#039; tags.&lt;br /&gt;
====== phase ====== &lt;br /&gt;
; id : the name for the phase&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;phases&amp;gt;&lt;br /&gt;
        &amp;lt;!-- sequence is important! --&amp;gt;&lt;br /&gt;
        &amp;lt;phase id=&amp;quot;staging&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;phase id=&amp;quot;update&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/phases&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== environments =====&lt;br /&gt;
Defines the distinguished environments.  Devices can have zero or more &#039;&#039;environments&#039;&#039; associated.  The environments a device is considered to be in must be passed as &amp;lt;code&amp;gt;?env=&amp;lt;/code&amp;gt;&#039;&#039;name1,name2,..&#039;&#039; URL query arg in the update url.  Update scripts for all environments listed will be applied. The default config file defines the environments &#039;&#039;intern&#039;&#039; and &#039;&#039;homeoffice&#039;&#039; but you can define your own if you like.&lt;br /&gt;
====== environment ====== &lt;br /&gt;
Each &#039;&#039;environment&#039;&#039; may have a number of sub-tags of type &#039;&#039;implies&#039;&#039;. It contains the &#039;&#039;id&#039;&#039; of another &#039;&#039;environment&#039;&#039;.   If a device is in an environment with an &#039;&#039;implies&#039;&#039; sub-tag, it is assumed that it is in the implied environment also. &lt;br /&gt;
; id : the name for the environment&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;environments&amp;gt;&lt;br /&gt;
        &amp;lt;environment id=&#039;hq&#039;&amp;gt;&lt;br /&gt;
            &amp;lt;implies&amp;gt;intranet&amp;lt;/implies&amp;gt;&lt;br /&gt;
        &amp;lt;/environment&amp;gt;&lt;br /&gt;
        &amp;lt;environment id=&#039;intranet&#039;/&amp;gt;&lt;br /&gt;
        &amp;lt;environment id=&#039;homeoffice&#039;/&amp;gt;&lt;br /&gt;
    &amp;lt;/environments&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== classes =====&lt;br /&gt;
Defines the available device classes.  Devices of different classes (e.g. phones and gateways) can have different update scripts. The device class is derived from the &amp;lt;code&amp;gt;#t&amp;lt;/code&amp;gt; (device type) query arg of the update script URL (which is why you must configure it in the update URL, see above).  By default, the classes &#039;&#039;phone&#039;&#039; and &#039;&#039;gw&#039;&#039; are recognized. A given device can be in multiple classes and will execute all update scripts available for these classes. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
    &amp;lt;classes&amp;gt;&lt;br /&gt;
        &amp;lt;class id=&amp;quot;gw&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;model&amp;gt;ip0010&amp;lt;/model&amp;gt;&lt;br /&gt;
            ...&lt;br /&gt;
        &amp;lt;/class&amp;gt;&lt;br /&gt;
        &amp;lt;class id=&amp;quot;phone&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;model&amp;gt;ip110&amp;lt;/model&amp;gt;&lt;br /&gt;
            ...&lt;br /&gt;
        &amp;lt;/class&amp;gt;&lt;br /&gt;
    &amp;lt;/classes&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====== class ======&lt;br /&gt;
Each &#039;&#039;class&#039;&#039; has a number of sub-tags of type &#039;&#039;model&#039;&#039;. It contains the value replaced for the &amp;lt;code&amp;gt;#t&amp;lt;/code&amp;gt; query arg.&lt;br /&gt;
; id : the name of the class&lt;br /&gt;
&lt;br /&gt;
===== stdargs =====&lt;br /&gt;
Better don&#039;t touch :-)&lt;br /&gt;
&lt;br /&gt;
===Testing===&lt;br /&gt;
To test your installation, you can simply use your browser simulating your device (it is convenient to use your browsers &#039;&#039;view source&#039;&#039; function to inspect the result). &lt;br /&gt;
&lt;br /&gt;
==== Cache ====&lt;br /&gt;
Open the update URL with the &amp;lt;code&amp;gt;#t&amp;lt;/code&amp;gt; argument replaced by the simulated device type (e.g. &amp;lt;code&amp;gt;http://172.16.10.65/update.php?type=ip222&amp;lt;/code&amp;gt;).  You will see an update script.  The first line will look like &lt;br /&gt;
 # failed to use cached data (cache not current), retrieving info online&lt;br /&gt;
 # phase: ...&lt;br /&gt;
This is normal, as there is no cache yet.  Now simply open the URL again (by hitting F5 e.g.).  You will now see &lt;br /&gt;
 # firmware build info cache is current&lt;br /&gt;
If so, your firmware info retrieval and your cache works.&lt;br /&gt;
&lt;br /&gt;
if not, there is something wrong with your master/info URL or your web server has no write access to the &amp;lt;code&amp;gt;cache&amp;lt;/code&amp;gt; sub-directory. &lt;br /&gt;
&lt;br /&gt;
==== Update Scripts ====&lt;br /&gt;
You should now see a line like &lt;br /&gt;
 # phase: staging, nextphase: update, environment: intern, type: ip222, classes: phone&lt;br /&gt;
in the update script.  This shows that the scripts for the first phasem &#039;&#039;staging&#039;&#039;, the default (i.e. first) environment &#039;&#039;intern&#039;&#039; and for devices of class &#039;&#039;phone&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The next lines will list the potential update scripts for this situation:&lt;br /&gt;
&lt;br /&gt;
 # possible files (from C:\sources\wiki-src\sample\php-update-server\sample\sources):&lt;br /&gt;
 # staging-phone-intern.txt (does not exist)&lt;br /&gt;
 # staging-phone-all.txt (does not exist)&lt;br /&gt;
 # staging-all-intern.txt (does not exist)&lt;br /&gt;
 # staging-all-all.txt (does not exist)&lt;br /&gt;
 # all-phone-intern.txt (does not exist)&lt;br /&gt;
 # all-phone-all.txt (does not exist)&lt;br /&gt;
 # all-all-intern.txt (does not exist)&lt;br /&gt;
 # all-all-all.txt (does not exist)&lt;br /&gt;
&lt;br /&gt;
Of course, as you have no scripts yet, all options are tagged as &#039;&#039;(does not exist)&#039;&#039;.  If one or more of such scripts exist, they will be executed in the order listed. &lt;br /&gt;
&lt;br /&gt;
==== Backup ====&lt;br /&gt;
&lt;br /&gt;
The next lines show you where the device backup will be sent to:&lt;br /&gt;
&lt;br /&gt;
 # backup&lt;br /&gt;
 mod cmd UP0 scfg http://172.16.10.65/update.php?mode=backup&amp;amp;hwid=#h ser hourly /force 1&lt;br /&gt;
&lt;br /&gt;
You can see that the backups are sent every hour (&#039;&#039;/force 1&#039;&#039;) if this has been configured in the &amp;lt;code&amp;gt;backup&amp;lt;/code&amp;gt; tag (see above).&lt;br /&gt;
&lt;br /&gt;
==== Firmware ====&lt;br /&gt;
The next block shows the required update of the firmware or boot code:&lt;br /&gt;
&lt;br /&gt;
 # current firmware (unknown) does not match required firmware (120663)&lt;br /&gt;
 mod cmd UP0 prot http://172.16.10.65/fw/120663/ ser 120663&lt;br /&gt;
 # current boot code (unknown) does not match required boot code (120502)&lt;br /&gt;
 mod cmd UP0 boot http://172.16.10.65/fw/120502/ ser 120502&lt;br /&gt;
 # make sure remaining update scripts are executed with up-to-date firmware&lt;br /&gt;
 iresetn&lt;br /&gt;
&lt;br /&gt;
In this example, the reference device is running firmware build 120663 and boot code build 120502.  The update server does not know the devices current firmware, so it creates an update command for both.  You can now add a &amp;lt;code&amp;gt;&amp;amp;PROT=120663&amp;lt;/code&amp;gt; query arg to the URL.  This tells the update server the firmware your device is running (a real life device will include this argument automatically, so there is no need to configure it anywhere).  When you retrieve the script again, no update command for the firmware will be included:&lt;br /&gt;
&lt;br /&gt;
 # current boot code (unknown) does not match required boot code (120502)&lt;br /&gt;
 mod cmd UP0 boot http://172.16.10.65/fw/120502/ ser 120502&lt;br /&gt;
 # make sure remaining update scripts are executed with up-to-date firmware&lt;br /&gt;
 iresetn&lt;br /&gt;
&lt;br /&gt;
==== Next Phase Switching ====&lt;br /&gt;
As you have 2 phases defined in your config file, the script will instruct the device to switch to the next phase (&#039;&#039;update&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 # warping from &#039;staging&#039; to &#039;update&#039; (url=http://172.16.10.65/update.php?type=#t&amp;amp;phase=update)&lt;br /&gt;
 config add UP1 /url http%3A%2F%2F172.16.10.65%2Fupdate.php%3Ftype%3D%2523t%26phase%3Dupdate&lt;br /&gt;
 config add UP1 /no-dhcp&lt;br /&gt;
 config write&lt;br /&gt;
 config activate&lt;br /&gt;
 &lt;br /&gt;
 # turn on fast polling&lt;br /&gt;
 mod cmd UP1 provision 5&lt;br /&gt;
&lt;br /&gt;
This is done by re-writing the update URL in the client.  You can simulate this by adding the &amp;lt;code&amp;gt;&amp;amp;phase=update&amp;lt;/code&amp;gt; query argument to your browser URL. You will see then: &lt;br /&gt;
&lt;br /&gt;
 # &#039;update&#039; is last phase&lt;br /&gt;
&lt;br /&gt;
==== Config File Re-Execution ====&lt;br /&gt;
In the last (that is, standard) phase, the config files will be executed only when changed.  This done using a [[Reference10:Concept_Update_Server#Check_command | check command ]]:&lt;br /&gt;
&lt;br /&gt;
 # skip remainder if there were no changes in config files&lt;br /&gt;
 mod cmd UP1 check ser d41d8cd98f00b204e9800998ecf8427e&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;serial&#039;&#039; &amp;lt;code&amp;gt;d41d8cd98f00b204e9800998ecf8427e&amp;lt;/code&amp;gt; is a hash code computed from the content of all script files that are valid for the calling device.  We can see how this works when we create an update script that is valid for the device.  You create a file called &amp;lt;code&amp;gt;all-all-all.txt&amp;lt;/code&amp;gt; in the update server directory and place something (e.g. a comment in it):&lt;br /&gt;
&lt;br /&gt;
You will now see that the script retrieved changes:&lt;br /&gt;
&lt;br /&gt;
 # skip remainder if there were no changes in config files&lt;br /&gt;
 mod cmd UP1 check ser 1e906fd3737281ebd4edbdf60a196fb3&lt;br /&gt;
 &lt;br /&gt;
 # 1 config files follow:&lt;br /&gt;
 # { begin script &#039;all-all-all.txt&#039; &lt;br /&gt;
 # my first update script&lt;br /&gt;
 &lt;br /&gt;
 # end script &#039;all-all-all.txt&#039; }&lt;br /&gt;
&lt;br /&gt;
The new &#039;&#039;serial&#039;&#039; &amp;lt;code&amp;gt;1e906fd3737281ebd4edbdf60a196fb3&amp;lt;/code&amp;gt; differs from the previous one. As a result, the devices will execute their update scripts whenever they change.&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
To debug update script execution in your real devices, you can &lt;br /&gt;
&lt;br /&gt;
* open the devices &amp;lt;code&amp;gt;debug.xml&amp;lt;/code&amp;gt; page (e.g. http://x.x.x.x/debug.xml)&lt;br /&gt;
* check the &#039;&#039;Update/Polling&#039;&#039;, &#039;&#039;Update/Execution&#039;&#039;, &#039;&#039;HTTP/Client&#039;&#039; and &#039;&#039;HTTP/verbose&#039;&#039; check marks&lt;br /&gt;
* force the update client in the device to run using the &amp;lt;code&amp;gt;mod cmd UP1 poll&amp;lt;/code&amp;gt; command (e.g. &amp;lt;code&amp;gt;http://x.x.x.x/!mod cmd UP1 poll&amp;lt;/code&amp;gt;)&lt;br /&gt;
* look at the traces (best with wireshark)&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
You can easily see the current status of your update server and scripts by calling the URL &amp;lt;code&amp;gt;http://&amp;lt;/code&amp;gt;&#039;&#039;your-update-server&#039;&#039;&amp;lt;code&amp;gt;/update.php?show&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Your own Update Scripts===&lt;br /&gt;
As you have seen, the update server will do some meaningful things (updating the device firmware and creating backups) even with no user supplied update scripts at all.  &lt;br /&gt;
&lt;br /&gt;
Feel free now to add your own update scripts.  All update script names must have the form &#039;&#039;phase&#039;&#039;&amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&#039;&#039;class&#039;&#039;&amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;&#039;&#039;environment&#039;&#039;&amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; (e.g. update-phone-intern.txt). If the word &amp;lt;code&amp;gt;all&amp;lt;/code&amp;gt; is used for any of the components, the file is executed for all phases, classes or environments respectively.&lt;br /&gt;
&lt;br /&gt;
When you retrieve the update script URL manually (e.g. using your browser), it will list all the potential update script files:&lt;br /&gt;
&lt;br /&gt;
 # possible files (from C:\sources\wiki-src\sample\php-update-server\sample\sources):&lt;br /&gt;
 # staging-phone-intern.txt (does not exist)&lt;br /&gt;
 # staging-phone-all.txt (does not exist)&lt;br /&gt;
 # staging-all-intern.txt (does not exist)&lt;br /&gt;
 # staging-all-all.txt (does not exist)&lt;br /&gt;
 # all-phone-intern.txt (does not exist)&lt;br /&gt;
 # all-phone-all.txt (does not exist)&lt;br /&gt;
 # all-all-intern.txt (does not exist)&lt;br /&gt;
 # all-all-all.txt (does not exist)&lt;br /&gt;
&lt;br /&gt;
Note that this list depends on &lt;br /&gt;
* the device&#039;s &#039;&#039;class&#039;&#039; (inferred from the &amp;lt;code&amp;gt;?type=#t&amp;lt;/code&amp;gt; query arg in the update URL)&lt;br /&gt;
* the device&#039;s &#039;&#039;environment&#039;&#039; (as specified by the optional &amp;lt;code&amp;gt;&amp;amp;env=&amp;lt;/code&amp;gt;&#039;&#039;environment-name&#039;&#039; query arg in the update URL)&lt;br /&gt;
&lt;br /&gt;
== Download ==&lt;br /&gt;
*[http://download.innovaphone.com/ice/wiki-src#php-update-server http://download.innovaphone.com/ice/wiki-src/] - download the complete file package of scripts and files described in this article&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [[Reference10:Concept_Update_Server]]&lt;br /&gt;
* [[Reference12r1:DHCP_client]]&lt;br /&gt;
* [[Reference10:Concept_Linux_Application_Platform]]&lt;br /&gt;
* [[Reference10:Concept_Provisioning]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Sample|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Peter.seyringer</name></author>
	</entry>
</feed>