@ -14,6 +14,7 @@ The base topology used is shown in Figure \ref{fig:topology}.
\end{figure}
\end{figure}
The continuous integration system is responsible for automatically building and publishing the firmware binary files, as soon as updated source code is available.
The continuous integration system is responsible for automatically building and publishing the firmware binary files, as soon as updated source code is available.
It is also in charge of assemble and publishing meta-information required for the update process.
Both systems are described in detail in the following section.
Both systems are described in detail in the following section.
Updates to the devices firmware is either actively triggered (manually or by the CI system) or on a regular schedule by the devices themselves.
Updates to the devices firmware is either actively triggered (manually or by the CI system) or on a regular schedule by the devices themselves.
@ -39,6 +40,7 @@ The according device type is provided as a string through a global constant at c
Device specific code is organized in a sub-folder for each device type.
Device specific code is organized in a sub-folder for each device type.
To build the software, a \textit{Makefile}\cite{make} is used, which provides a simple way for reproducible builds.
To build the software, a \textit{Makefile}\cite{make} is used, which provides a simple way for reproducible builds.
When a new build process is started, the build system scans for all device specific folders and calls the original build process for each of them.
When a new build process is started, the build system scans for all device specific folders and calls the original build process for each of them.
After the build of the firmware has finished, the build system also creates a fail for each device containing the build version and the firmware signatures.
The source code of the \textit{ESPer} project is published into a \textit{Git} source code repository.
The source code of the \textit{ESPer} project is published into a \textit{Git} source code repository.
To avoid interferences between different build environments on developers computers and roll out new versions as early as possible, the code has been integrated into a continuous integration (CI) system.
To avoid interferences between different build environments on developers computers and roll out new versions as early as possible, the code has been integrated into a continuous integration (CI) system.
@ -48,7 +50,6 @@ In the specific case, whenever a new version gets checked-in into the release br
Therefore, a \textit{drone} configuration file as shown in Listing~\ref{lst:drone} has been added to the source code as \texttt{.drone.yml}.
Therefore, a \textit{drone} configuration file as shown in Listing~\ref{lst:drone} has been added to the source code as \texttt{.drone.yml}.
\subsection{Device setup and flash layout}\label{flashlayout}
\subsection{Device setup and flash layout}\label{flashlayout}
Microcontroller boards based on the \textit{ESP8266} MCU are mostly following the same layout: the MCU is attached to a flash chip which contains the bootloader, firmware and other application data.
Microcontroller boards based on the \textit{ESP8266} MCU are mostly following the same layout: the MCU is attached to a flash chip which contains the bootloader, firmware and other application data.
@ -69,3 +70,11 @@ In case of an error the old firmware is kept unchanged and will be used until th
In addition to the two firmware ROMs, the flash provides room for the bootloader and its configuration.
In addition to the two firmware ROMs, the flash provides room for the bootloader and its configuration.
\subsection{Cryptographically securing the firmware update}
To ensure only valid firmware is running on the device, the update process is calculating and checking the firmwares signature.
To do so, \textit{curve25519}\cite{curve25519} and \textit{sha512}\cite{sha512} is used which is a modern secure method for signatures \cite{crypto-ftw}.
The signature is created by the build system for each of the two firmware ROMs during build time and is provided as meta-information beside the firmware binaries.
Therefor the build system must be equipped with the private key used to create the signatures.
In contrast, the Microcontroller does only need to know the according public key.
@ -11,16 +11,16 @@ Skipping the option results in the exclusion of the code for update management d
\subsubsection{Checking for updates}
\subsubsection{Checking for updates}
Initially, each device queries the update server regularly for the current firmware version and initializes the update process if remote and local versions differ.
Initially, each device queries the update server regularly for the current firmware version and initializes the update process if remote and local versions differ.
To do so, the update server provides a file for each device type containing the available version identifier, which is stored beside the firmware binary files.
These version identifier files are provided by the update server using \textit{HTTP 1.1}\cite{HTTP_1.1} under the following path pattern: \texttt{\$\{DEVICE\}.version} (whereas \texttt{\$\{DEVICE\}} is the device type name).
To do so, the update server provides a file for each device type containing the available version identifier, which is stored beside the firmware binary files with other meta-information.
These meta-information files are provided by the update server using \textit{HTTP 1.1}\cite{HTTP_1.1} under the following path pattern: \texttt{\$\{DEVICE\}.version} (whereas \texttt{\$\{DEVICE\}} is the device type name).
The version identifier can be an arbitrary string as the content is not interpreted semantically but only compared to the version identifier used during build time.
The version identifier can be an arbitrary string as the content is not interpreted semantically but only compared to the version identifier used during build time.
Each device tries to fetch the version identifier file once every hour.
After the version identifier file has been downloaded successfully, the whole file content is compared to the version identifier provided during build time.
Each device tries to fetch the meta-information file once every hour.
After the file has been downloaded successfully, the version identifier is extracted and compared to the version identifier provided during build time.
If the version identifiers differ, the update process is initialized; in cases where the download has failed, the update server or the network connection was not available or any other error occurred, another attempt will be made at the next interval.
If the version identifiers differ, the update process is initialized; in cases where the download has failed, the update server or the network connection was not available or any other error occurred, another attempt will be made at the next interval.
In addition to the interval, a special \textit{MQTT} topic shared by all devices is subscribed on device startup: \texttt{\$\{MQTT\_REALM\}/update}.
In addition to the interval, a special \textit{MQTT} topic shared by all devices is subscribed on device startup: \texttt{\$\{MQTT\_REALM\}/update}.
Every time a message is received on this topic, a fetch attempt for the version identifier file is triggered.
Every time a message is received on this topic, a fetch attempt for the meta-information file is triggered and the process restarts.
This allows faster roll-outs of updates and finer control for manual maintenance.
This allows faster roll-outs of updates and finer control for manual maintenance.
@ -74,7 +74,7 @@ if (bootconf.current_rom == 0) {
\end{lstlisting}
\end{lstlisting}
For installing a firmware update, the new firmware binary file is downloaded using an HTTP GET request.
For installing a firmware update, the new firmware binary file is downloaded using an HTTP GET request.
The update server provides these files in the exact same way as it provides the version identifier files, but the path pattern differs: the suffixes \texttt{.rom0} and \texttt{.rom1} are used to provide the firmware binary files for the first and second slot respectively.
The update server provides these files in the exact same way as it provides the meta-information files, but the path pattern differs: the suffixes \texttt{.rom0} and \texttt{.rom1} are used to provide the firmware binary files for the first and second slot respectively.
The firmware files provided on the update server are the exact same ones as used to initially flash the chip for the according version.
The firmware files provided on the update server are the exact same ones as used to initially flash the chip for the according version.
Using the same files for flashing and updating allows better debugging by eliminating errors related to the update process itself and makes development and initial installation very easy.
Using the same files for flashing and updating allows better debugging by eliminating errors related to the update process itself and makes development and initial installation very easy.
Listing~\ref{lst:choosing_rom} shows the algorithm used to determine the download address and reconfigure the bootloader.
Listing~\ref{lst:choosing_rom} shows the algorithm used to determine the download address and reconfigure the bootloader.
@ -38,7 +38,7 @@ Another \textit{Makefile} has been created which scans a project subdirectory an
For each of these directories, the other \textit{Makefile} is called and the subdirectories name is used as \texttt{DEVICE} parameter.
For each of these directories, the other \textit{Makefile} is called and the subdirectories name is used as \texttt{DEVICE} parameter.
By splitting the build and recompiling the framework each time before intermixing it with the device specific code, the device type identifier can be used inside the shared framework code.
By splitting the build and recompiling the framework each time before intermixing it with the device specific code, the device type identifier can be used inside the shared framework code.
While building a devices firmware, the version identifier file used during updates is also created and stored beside the binary firmware image.
While building a devices firmware, the meta-information file used during updates is also created and stored beside the binary firmware image.
For development, each device can be build separately by using the device type identifier as \textit{Makefile} target.
For development, each device can be build separately by using the device type identifier as \textit{Makefile} target.
In addition the prefix \texttt{/flash} can be used to flash a specific firmware.
In addition the prefix \texttt{/flash} can be used to flash a specific firmware.