\chapter{Implementation}
\label{chapter-implementation}
\glsresetall

This chapter presents the implementation of the SmartCGMS concept proposed in chapter \ref{chap-proposed-system}. The first section describes modifications to the SmartCGMS codebase. The second section describes the implementation of the proposed filter preprocessor tool. The third section describes the SmartCGMS concept \gls{api}. The fourth section describes filters implemented to test and showcase the proposed concept. The last section describes the platforms for which the concept application has been compiled and the differences between the platforms.


\section{SmartCGMS Codebase}

As already discussed in chapter \ref{chap-proposed-system}, to make the SmartCGMS concept easily portable to new embedded platforms, the SmartCMGS concept application needs to be linked statically instead of dynamically. This section describes the necessary changes to the SmartCGMS codebase to compile the SmartCGMS concept application for low-power platforms.

\subsection{Functions Incompatible with Embedded Environments}

The original SmartCGMS codebase contains functions that can not be supported in a portable embedded environment and functions related to SmartCGMS's dynamic linking nature. These functions were either removed or modified to avoid any unwanted side effects (e.g., by removing the function body and returning a default value). The decision of whether to remove a function or modify it was made individually for each function. The goal was to keep the code readable and minimize modifications to the source code. Most of the modifications are implemented using preprocessor \texttt{\#if defined()} directives, with the macro name \texttt{EMBEDDED}.

\subsubsection{SmartCGMS Interfaces}

The SmartCGMS common library defines interfaces that each entity must implement (e.g., \texttt{scgms::IFilter} for filters). Some of the interfaces contain functions that rely on filesystem \gls{api}. As the low-power platforms selected for the SmartCGMS concept do not support C++ standard filesystem \gls{api}, these functions were removed from the interfaces. 

\subsection{Resolving Symbols}

When a SmartCGMS application is started, it loads all the dynamic libraries from its working directory. To resolve functions between the SmartCGMS core and common dynamic libraries, it uses a function called \texttt{resolve\_symbol}. It is a wrapper for the \texttt{GetProcAddress} function, which retrieves the address of an exported function from a dynamic library. In the SmartCGMS concept, the \texttt{resolve\_symbol} function can call the functions directly as the concept applications are compiled as monolithic executables. The function in the SmartCGMS concept codebase is defined in a new file \texttt{staticLink.cpp} and is called \texttt{resolve\_symbol\_static}. To be able to resolve the functions, the headers declaring the functions need to be included in the file implementing the \texttt{resolve\_symbol\_static} function. An example of how the functions are resolved can be seen in figure \ref{fig:resolve-symbol}.

\begin{figure}[!htbp]
\begin{lstlisting}[language=C++, caption = Example implementation of the resolve\_symbol\_static() function, label = fig:resolve-symbol ]
void* resolve_symbol(const char *symbol_name) noexcept
{
  if (strcmp(symbol_name, "create_device_event") == 0) 
  {
    return reinterpret_cast<void*>(create_device_event);
  }
  if (strcmp(symbol_name, "get_filter_descriptors") == 0) 
  {
    return reinterpret_cast<void*>(get_all_descriptors);
  }
  if (strcmp(symbol_name, "execute_filter_configuration") == 0) 
  {
    return reinterpret_cast<void*>(execute_filter_configuration);
  }
  return nullptr;
}
\end{lstlisting}
\end{figure}


\subsection{Managing Entities}
\label{sec:scgms-codebase}

To manage entities, SmartCGMS uses a class called \texttt{CLoaded\_Filters}. This class stores information about each entity (e.g., its descriptors, handle to its dynamic library). On startup, SmartCGMS checks each dynamic library in its project folder if it exports functions defined for a SmartCGMS entity. If a library exports the defined functions, it is then stored in this class. When an action is requested on a specific entity, the \texttt{CLoaded\_Filters} class can then call the corresponding function by using the dynamic library handle. The entities are identified by a \gls{guid}. The \texttt{CLoaded\_Filters} class does not store the \glspl{guid} of the entities. When executing a function (e.g., \texttt{do\_create\_filter}), it calls the function from each dynamic library until one of the calls returns a success return code (each entity checks the \gls{guid} passed as an argument to the function and executes the function only if the \gls{guid} matches its own). The \texttt{CLoaded\_Filters} class is replaced in the SmartCGMS concept by a class with the same name. The class is completely generated by the preprocessor tool.

\subsubsection*{Filter Descriptors}

The newly implemented class stores the filter descriptors (\texttt{TFilter\_Descriptor}) in an \texttt{std::vector}. These descriptors are loaded when the class is instantiated. To load the descriptors, the class defines a lambda function to copy the descriptors of each filter to the \texttt{CLoaded\_Filters} class, see \ref{fig:lambda}.


\begin{figure}[!htbp]
\begin{lstlisting}[style=myCpp, caption = Lambda function to replace \texttt{do\_get\_filter\_descriptors} calls to dynamic libraries, label = fig:lambda, basicstyle=\footnotesize\ttfamily ]
using FilterDescriptorFunction = 
HRESULT(*)(scgms::TFilter_Descriptor**, scgms::TFilter_Descriptor**);

auto get_descriptors = [&](FilterDescriptorFunction get_filter_descriptors)
{
  scgms::TFilter_Descriptor *desc_begin, *desc_end;
  bool result = get_filter_descriptors(&desc_begin, &desc_end) == S_OK;
  if (result)
  {
    std::copy(desc_begin, desc_end, std::back_inserter(mFilter_Descriptors));
  }
};
\end{lstlisting}
\end{figure}

The exported \texttt{do\_get\_filter\_descriptors} function of each filter is passed as a parameter to the lambda function and then the filter descriptors are copied to the \texttt{std::vector} \texttt{mFilter\_Descriptors} in \texttt{CLoaded\_Filters} class.

\subsubsection*{Creating Filters}

The original SmartCGMS codebase contains a function called \texttt{create\_filter\_body}. This function is called when a filter needs to be constructed. The filter is specified by its \gls{guid}. The function iterates through the filters' dynamic libraries stored in \texttt{CLoaded\_Filters} and calls the \texttt{do\_create\_filter} functions until one of the calls returns signaling success. As the SmartCGMS concept's \texttt{CLoaded\_Filters} class only stores the filter descriptors and can not call the function of the filters, the \texttt{create\_filter\_body} function also needs to be replaced. The new implementation simply unrolls the loop of the original function and in each step calls the \texttt{do\_create\_filter} function for a different filter as seen in listing \ref{fig:create-filter}.

\begin{figure}[!htbp]
\begin{lstlisting}[style=myCpp, caption = Example implementation of the create\_filter\_body() 
function, label = fig:create-filter, basicstyle=\footnotesize\ttfamily]
scgms::SFilter create_filter_body(const GUID &id, scgms::IFilter *next_filter)
{
  scgms::SFilter result;
  scgms::IFilter *filter;

  if (do_create_filter_data_filter(&id, next_filter, &filter) == S_OK)
  {
    result = refcnt::make_shared_reference_ext<scgms::SFilter, scgms::IFilter>(filter, false);
    return result;
  }
  if (do_create_filter_ema_filter(&id, next_filter, &filter) == S_OK)
  {
    result = refcnt::make_shared_reference_ext<scgms::SFilter, scgms::IFilter>(filter, false);
    return result;
  }
  if (do_create_filter_watchdog_filter(&id, next_filter, &filter) == S_OK)
  {
    result = refcnt::make_shared_reference_ext<scgms::SFilter, scgms::IFilter>(filter, false);
    return result;
  }
  if (do_create_filter_print_filter(&id, next_filter, &filter) == S_OK)
  {
    result = refcnt::make_shared_reference_ext<scgms::SFilter, scgms::IFilter>(filter, false);
    return result;
  }

  return result;
}

\end{lstlisting}
\end{figure}


\newpage
\section{Filter Preprocessor}

As the original SmartCGMS is a set of dynamic libraries and each filter is its own dynamic library, the exported functions of each filter can have the same function signature and not cause conflicts at the linking stage when building a SmartCGMS application. In the SmartCGMS concept, the function names are modified, as seen in figure \ref{fig:create-filter}. This is to prevent linking conflicts. To prevent developers from having to write separate filters for the original SmartCGMS and the SmartCGMS concept and to keep SmartCGMS entities' \gls{api} unchanged, a filter preprocessor tool has been proposed and implemented.

The source code modifications described in section \ref{sec:scgms-codebase} all come from the same source and header files \texttt{filters.cpp} and \texttt{filters.h}. These files are not included in the SmartCGMS concept codebase. Instead, they are generated by the filter preprocessor tool and added for each filter chain subsequently. The reason is that each additional filter in a filter chain requires its functions to be added to the \texttt{filters.cpp} source code file.

The filter preprocessor tool takes a folder containing an original SmartCGMS filter chain source code as input and generates a folder containing a SmartCGMS concept filter chain source code as output. The expected input folder structure is that each subfolder of the input folder contains a single filter implementation. The name of the root folder of each filter is used to identify the filters in the generated files. The source code of each filter is searched and then modified by appending the root folder name as a suffix to the functions that are exported by the filters (\texttt{do\_create\_filter} and \texttt{do\_get\_filter\_descriptors}). The definitions of the new functions are added to the generated header file. All the modified names of the functions are stored and then used to generate the body of the \texttt{create\_filter\_body} function and the function to gather filter descriptors to \texttt{CLoaded\_Filters} using the lambda function from listing \ref{fig:lambda}.

SmartCGMS offers a way to load the filter chain configuration from memory. The filter preprocessor tool copies the .ini configuration file to a C++ raw string literal from which it can then be loaded in the SmartCGMS concept.

The filter preprocessor does not check if the provided filter chain contains all filters specified by the configuration file. If there is a filter specified in the configuration but the source code files for it are not provided to the preprocessor, the issue will be discovered at runtime after building the SmartCGMS concept application. In case there is an error in the configuration of the filter chain, it can be resolved by uploading a new configuration at runtime. If the error comes from a missing filter, then the whole application has to be rebuilt.

\section{SmartCGMS Concept API}
\label{sec:scgms_api}

To interact with the SmartCGMS concept, the original SmartCGMS \gls{api} can be used. Only parts of the original SmartCGMS \gls{api} have been implemented for the SmartCGMS concept due to time constraints. Additionally, a new minimal C-style \gls{api} (similar to the simple interface of SmartCGMS) has been implemented to test the functionality of the proposed system. The introduced \gls{api} allows usage of the SmartCGMS concept without any underlying knowledge of SmartCGMS. There are three interface functions:

\begin{itemize}
    \item \texttt{int build\_filter\_chain(const char*  configuration\_input)}
    \item \texttt{const char* get\_config\_data()}
    \item \texttt{void create\_event(const SCGMS\_Event* event)}
\end{itemize}

The \texttt{build\_filter\_chain} function is used to construct the filter chain. It takes a C string as input. If an input string is not provided, the filter chain is built using the configuration with which the SmartCGMS concept application has been compiled. The default configuration can be retrieved as a C string using the \texttt{get\_config\_data} function. This allows an application using the SmartCGMS concept to easily edit the default filter parameters. The configuration can be retrieved before the filter chain is built. The last function \texttt{create\_event()} injects events into the filter chain. This function can be used to send data to the filter chain when it is received outside of the SmartCGMS filter chain. The SmartCGMS filter chain can be shut down by creating a shutdown event.

\section{Filters}
\label{sec:filters}
Four filters have been developed for the SmartCGMS concept demonstration:

\begin{itemize}
    \item Data reading filter
    \item Data transformation filter
    \item Data visualization filter
    \item Watchdog filter
\end{itemize}

The filters have been developed to support all the platforms specified in section \ref{sec:supported-platforms}. In cases where the implementation needed to differ, preprocessor directives were used. The filters were implemented as dynamic libraries to maintain compatibility with the original SmartCGMS. Filters that do not rely on platform-specific features can be used as dynamic libraries on platforms supported by the original SmartCGMS. The following sections describe the implemented filters. 

\subsection{Data Reading Filter}

The data reading filter is meant to be an input filter of a filter chain, but it can also be used to store statistics at the end of a filter chain. The common part for all platforms acts as a simple event statistic counter. The filter logs the number of all events passing through it. The filter additionally logs the number of error events, warning events, level events, and information events. When the filter receives a shutdown event, it prints the gathered statistics to the console. An example scenario of how the data reading filter could be used is depicted in figure \ref{fig:two_data_filters}. One data reading filter can be set up to log incoming events into the filter chain and one can be positioned at the end of the filter chain. On the filter chain shutdown, the statistics can be compared and, for example, a number of error events generated by the filter chain can be calculated.

\begin{figure}[htpb]
  \centering
  \includegraphics[width=1\textwidth]{figures/two_data_filters.PNG}
  \caption{Example of a SmartCGMS filter chain containing data reading filters at the beginning and the end to calculate event statistics.} \label{fig:two_data_filters}
\end{figure}

The data reading filter for the ESP32 platform creates a new task that listens on the UART interface. It expects to receive numbers in the double-precision format on the UART interface. Whenever a number is received, a SmartCGMS level event is generated using the received number as the level value and sent into the filter chain. The UART task is created during the configuration of the data reading filter. The filter can still process events originating from previous filters or outside the filter chain using the \texttt{Execute} function. The task creation during the filter configuration is optional and is set using a \texttt{create\_task} parameter in the configuration file to either \texttt{true} or \texttt{false}. On the Raspberry Pi Zero W platform, the data reading filter can create a task that reads level values from an \texttt{input.h} file that is compiled with the filter source code. When a shutdown event is received by the data reading filter and the task has been started, the filter shuts it down synchronously.

The \gls{wasm} platforms do not support creating a task (or a \gls{pthread}) for reading or generating data since the selected environments for \gls{wasm} offer only experimental support for \glspl{pthread} (\gls{wamr}) or since it would greatly increase resource management and synchronization complexity (using JavaScript multithreading on the web). The parameter \texttt{create\_task} on these platforms is ignored.

\subsection{Data Transformation Filter}

The data transformation filter implementation is portable across all the platforms supported by the SmartCGMS concept and the original SmartCGMS. The filter computes the \gls{ema} value of the event levels. An \gls{ema} is a moving average that applies decreasing weight to older values. The formula for the \gls{ema} calculated in the filter can be seen in listing \ref{fig:ema}. The accumulator value is the \gls{ema} value. The alpha is a constant parameter that modifies the ratio at which the weight of older data decreases.
When constructing the filter the alpha constant is read from the configuration file using an \texttt{alpha} parameter that can be set to a value between 0 and 1. The filter computes the \gls{ema} from the level value of SmartCGMS level events. All other events are passed through unmodified.

\begin{figure}[!htbp]
\begin{lstlisting}[language=C++, caption = Exponential moving average calculation, label = fig:ema ]
accumulator = (alpha * event.level()) + (1.0 - alpha) * accumulator;
\end{lstlisting}
\end{figure}

\subsection{Data Visualization Filter}
\label{subsec:datavis}

The data visualization filter has a specific implementation for each platform. It does not have any parameters that can be specified in the configuration file and it does not modify the passing events in any way. On embedded platforms and in the \gls{wasm} environment targeted at standalone \gls{wasm} runtimes, the filter prints the event level values and information event strings. For each event, it also prints the device time. On the embedded platforms the data is sent to UART. In the \gls{wasm} standalone runtime, the \gls{wasi} is used to print the data to the console on the hosting system. 

For the \gls{wasm} environment targeting the web, Emscripten is used to call a JavaScript function from the C++ source code. Emscripten provides a C-style function \texttt{emscripten\_run\_script} that takes a C string as an argument and executes it as JavaScript code in the host environment. The call to the 
\texttt{emscripten\_run\_script} function is shown in listing \ref{fig:javascript_emcc}. The generated JavaScript code can be seen in listing \ref{fig:javascript}. The generated JavaScript code creates a message object and calls a function \texttt{postData} providing the object as an argument. This approach allows developers to tailor the \texttt{postData} function implementation to a specific application and it does not expose the implementation to the data visualization filter. The message object can be extended with more information about the event, but for demonstration purposes, it has been kept simple. 

\begin{figure}[!htbp]
\begin{lstlisting}[language=C++, caption = Calling JavaScript to post event data to the web environment running the SmartCGMS \gls{wasm} module., label = fig:javascript_emcc]
std::string js_code = R"(
  var message = {
  data_level: )" + std::to_string(event.level()) + R"(,
  data_device_time: )" + Rat_Time_To_Local_Time_Str(event.device_time(), "%H:%M:%S") + R"(,
  data_logical_time: )" + std::to_string(event.logical_time()) +  R"(
  };
  postData(message);
  )";
emscripten_run_script(js_code.c_str());
\end{lstlisting}
\end{figure}

\begin{figure}[!htbp]
\begin{lstlisting}[language=JavaScript, caption = An example of JavaScript code contained in the \texttt{js\_code} string from listing \ref{fig:javascript_emcc}, label = fig:javascript ]
var message = {
    data_level: 101.348,
    data_device_time: 13:45:22,
    data_logical_time: 76
};			
postData(message);
\end{lstlisting}
\end{figure}

\newpage
The SmartCGMS concept application can be executed asynchronously on the web as a JavaScript web worker (JavaScript thread equivalent). The \texttt{postData} function then has to be changed to \texttt{self.postMessage}. This posts the message object to the thread that spawned the SmartCGMS web worker. The object can then be handled inside \texttt{worker.onmessage} handler in the thread that controls the SmartCGMS web worker.



\subsection{Watchdog Filter}

The purpose of the watchdog filter is to ensure a correct run of the filter chain, to notify about any unusual behavior, and possibly to shut the filter chain down. The implementation monitors two things. Firstly, if the filter chain is active (an event passing through before a specified timeout). Secondly, if the events in the filter chain are chronologically ordered (the logical event time is increasing). The first condition is monitored with a task that runs asynchronously. The task has a set timer, when it expires the watchdog checks whether any events passed through. If the watchdog hasn't been reset by a passing event, it triggers an action (function \texttt{Trigger} is called). When the \texttt{Do\_Execute} function is called (upon receiving an event), it calls a \texttt{Kick} function. This function takes the event's logical time as a parameter and it compares it to the logical time of the previous event. If the new event's logical time is lower than the previous event's time (the new event is older) the watchdog also triggers an action. 

The watchdog task is implemented as a \gls{pthread} for the \gls{wasm} platforms and the ESP32. For Raspberry Pi Zero W the watchdog task is implemented as a FreeRTOS task. In case of porting this filter to a new platform, it is required to implement the \texttt{Trigger} function and to create the watchdog task during the filter configuration. The watchdog filter has one parameter - the timeout timer interval in milliseconds.

\section{Supported Platforms}
\label{sec:supported-platforms}

This section describes platforms for which an environment was created to support the SmartCGMS concept. There are 4 platforms (in brackets are specified the platform's \glspl{isa}):

\begin{itemize}
    \item Raspberry Pi Zero W (ARMv6)
    \item ESP32 (Xtensa)
    \item \gls{wasm} targeted at the web (x86-64)
    \item \gls{wasm} targeted at a standalone runtime (portable)
\end{itemize}


The Raspberry Pi Zero W and ESP32 represent embedded devices. Their environment is based on FreeRTOS. The ESP32 environment uses the \gls{espidf}, which offers additional software components. The \gls{wasm} platforms use the standard C library built on top of \gls{wasi} system calls. SmartCGMS uses a \texttt{winapi\_mapping.cpp} file to provide a wrapper around functions from different platforms (e.g., function to allocate memory). Functions to allocate memory for each platform were added to this file.

The directory layout is similar for all platforms. The SmartCGMS codebase and filter chain are separated as proposed in section \ref{subsec:modularity}. The platform environment from section \ref{subsec:modularity} refers to the whole directory of the SmartCGMS concept application for a specific platform (including build scripts, CMake files, and FreeRTOS source code).
 
A Python script has been implemented to assist the development. First, it downloads the platform environment from a remote repository, followed by the SmartCGMS codebase. The filter chain is taken from an input directory. The Python script then uses the preprocessor tool to modify the filters' source code and generate the required files. Finally, all the source code files are combined in the downloaded platform environment directory. Each platform uses CMake to simplify the build process of the SmartCGMS concept.

The platform environments and the Python script generating the build directories are targeted at GNU/Linux. Therefore, the Python script has been Dockerized to allow development on other platforms. The Python script generates an additional CMake file that contains environment variables specific for each platform (e.g., path to ARM embedded toolchain for Raspberry Pi Zero W or path to the \gls{espidf} for the ESP32). The SmartCGMS concept application can then be built using a simple build shell script that is also provided for each platform. To avoid local installation of multiple toolchains, Docker images that are provided for the \gls{wasm} and ESP32 platforms on their official repositories can be used.

\subsection{Raspberry Pi Zero W}

The ARMv6 \gls{isa} requires an implementation of the C++ atomic library helper functions to be provided, as it does not implement the atomic library \parencite{arm}.  This step has been omitted due to project time constraints and atomic variables in the SmartCGMS codebase have been replaced by their non-atomic equivalents. Preprocessor directives have been used to maintain atomicity on other platforms.

A custom port of FreeRTOS has been used. FreeRTOS-Plus-POSIX extension has been added to allow all platforms to use \glspl{pthread} to manage tasks. To allocate memory, FreeRTOS \texttt{pvPortMalloc} needs to be called. 

When creating a SmartCGMS concept application for the Raspberry Pi Zero W the data for the filter chain (e.g. blood glucose levels from a sensor sent over UART) can be received and processed directly in the SmartCGMS filter chain using a specialized filter. The data can also be received and processed in a separate FreeRTOS task that sends the events into the SmartCGMS filter chain. Using the second approach, the SmartCGMS concept can be easily implemented into an existing FreeRTOS application.

\subsection{ESP32}

The ESP32 environment uses the \gls{espidf}. The SmartCGMS concept application is divided into three distinct parts: the SmartCGMS codebase, the filter chain, and the main application. The first two parts are implemented as \gls{espidf} components. The main application then uses these components. The SmartCGMS codebase and the filter chain components depend on each other and can not be used on their own. The filter chain component's name is \texttt{filters}. The SmartCGMS codebase component is called \texttt{scgms\_embedded}. The main application is expected to interact with the \texttt{scgms\_embedded} component. The \gls{api} functions described in section \ref{sec:scgms_api} are defined in this component in a header file \texttt{scgms.h}.

Similarly to the Raspberry Pi Zero W, the ESP32 SmartCGMS concept can be used in two ways. Either the main application can receive data and then send it into the SmartCGMS filter chain, or it can build a filter chain that creates its own FreeRTOS task for receiving data (e.g., by using the UART data reading filter from section \ref{sec:filters}).


\subsection{\gls{wasm} Standalone Runtime}

For the standalone \gls{wasm} runtime, the SmartCGMS concept application is compiled to the \gls{wasm} binary format using Clang. To provide C standard library implementation and the \gls{wasi}, \gls{wasi} \gls{sdk} is used for the build. The platform environment has a similar structure to the embedded environments. It contains two directories: the SmartCGMS codebase and the filter chain, plus additional files like CMake files, build scripts, and a \textit{main.cpp} source code file. To control what functions are exported from the \gls{wasm} module, the \texttt{main.cpp} and the \texttt{CMakeLists.txt} file can be edited. Currently, the \gls{wasm} module exports the main function, which is started directly after loading the module. The main function builds the filter chain specified by the configuration file provided by the preprocessor. The \gls{wasm} module can be optionally set up as a library (without a main function). The \gls{wasm} compiled SmartCGMS concept supports asynchronous filters. A filter can create a thread using \glspl{pthread}. Although \gls{wasi} \gls{sdk} offers only experimental support for threads. The \gls{wasm} module compiled for the standalone \gls{wasm} runtime can be executed even on the web. To run the \gls{wasm} module, the platform needs to support \gls{wasi} calls used in the module. The \gls{wasi} calls may differ for each \gls{wasm} SmartCGMS concept application depending on the used filter chain (e.g., if using a filter with \glspl{pthread}).  

The standalone \gls{wasm} runtime selected for this project is \gls{wamr}. Relevant features that are supported by \gls{wamr} are \glspl{pthread} and \gls{wasi}. \gls{wamr} also supports multiple \glspl{isa} including Xtensa, x86-64, and ARM. \gls{wamr} provides a command line interface application called \texttt{iwasm}. The application for this project has been compiled and used on GNU/Linux, though other x86-64 systems are also supported (e.g., MacOS and Windows). A \gls{wamr} application for the ESP32 is also available. It is based on the \gls{espidf} and loads the \gls{wasm} module from a C-style byte array from memory. To be able to execute the \gls{wasm} module on the ESP32, the build script in the \gls{wasm} standalone runtime environment also generates a C/C++ header file containing a byte array with the \gls{wasm} module. As \gls{wasm} is a binary format, this is achieved by hex dumping the \gls{wasm} into the byte array. Although \gls{wamr} supports ARM \gls{isa}, the Raspberry Pi Zero W platform is not officially supported, and neither is FreeRTOS. 


\subsection{\gls{wasm} Targeted at The Web}

While the \gls{wasm} module compiled using \gls{wasi} \gls{sdk} can be executed in a web browser, it is easier to use a \gls{wasm} module that was compiled using the Emscripten toolchain. The reason is that Emscripten also generates JavaScript wrapper code to simplify the module's loading. Emscripten can also directly generate an HTML file that loads and executes the \gls{wasm} module. The platform environment directory structure is the same as the directory structure for compiling \gls{wasm} for standalone runtimes. One folder contains the SmartCGMS codebase, one contains the filter chain, and then there is an additional \texttt{main.cpp} file, which interacts with the SmartCGMS concept \gls{api} and defines functions that are exported by the \gls{wasm} module. The \texttt{CMakeLists.txt} does not have to be edited when exporting new symbols, as the Emscripten toolchain can automatically handle symbol exports from C++ code to JavaScript, see listing \ref{fig:emcc_keepalive}. Emscripten features that are relevant for this project are multi-threading support and the ability to execute JavaScript code inside the \gls{wasm} module.



\begin{figure}[!htbp]
\begin{lstlisting}[language=C++, caption = An example of exporting symbols from \gls{wasm} module using Emscripten, label = fig:emcc_keepalive ]
extern "C" {
EMSCRIPTEN_KEEPALIVE
const char* get_config()
{
    return get_config_data();
}
}
\end{lstlisting}
\end{figure}


The \gls{wasm} module compiled in the environment targeted at the web can also be executed in standalone runtimes, though \gls{wamr} does not recommend running Emscripten compiled \gls{wasm} modules. Therefore, it is recommended to use \gls{wasm} modules built in this environment only in the web browser. When the \gls{wasm} SmartCGMS concept application is built, two files are created: the \gls{wasm} module and a JavaScript code to load and execute the module. Additionally, a third file might be generated: a JavaScript web worker code. This file is generated when threads are created inside the SmartCGMS concept application. Using the JavaScript code, the module can be easily embedded into a webpage. To demonstrate the functionality of the \gls{wasm} SmartCGMS concept, a demo webpage was created. The webpage uses JavaScript to load the compiled SmartCGMS concept \gls{wasm} module. It provides buttons to build the filter chain and then injects events into it. The events are displayed using \texttt{Chart.js} (JavaScript data visualization library) in a line graph. The graph displays the original event level value injected into the filter chain and then the modified value provided by the data visualization filter (using the \texttt{postData} function), which is described in section \ref{subsec:datavis}. The filter chain can be built either with the configuration it was compiled with or with a custom configuration supplied from the webpage. The webpage has an editable text field to edit the configuration, which can then be sent to the SmartCGMS \gls{wasm} module. To simplify the creation of a custom configuration, the default configuration can be loaded from the SmartCGMS \gls{wasm} module (using the \gls{api} function: \texttt{get\_config\_data()}). A filter chain configuration and event data in the line graph can be seen in figure \ref{fig:webpage_graph}. The data to the filters are pseudo-randomly generated, and the filter chain consists of the four filters from section \ref{sec:filters} in the same order as they are described. Additional output from the SmartCGMS concept application can be seen in the web browser developer console, shown in figure \ref{fig:webpage_console}.  

\begin{figure}[htpb]
  \centering
  \includegraphics[width=1\textwidth]{figures/webpage.PNG}
  \caption{SmartCGMS \gls{wasm} demo webpage: Filter chain configuration and pseudo-randomly generated data processed by the filter chain displayed in a \texttt{Chart.js} graph.} \label{fig:webpage_graph}
\end{figure}

\begin{figure}[htpb]
  \centering
  \includegraphics[width=0.7\textwidth]{figures/console.PNG}
  \caption{SmartCGMS \gls{wasm} demo webpage: Additional output printed to the Google Chrome developer console by the SmartCGMS \gls{wasm} module} \label{fig:webpage_console}
\end{figure}

\newpage
\subsubsection*{SmartCGMS Web Demo}
\label{sec:webmodel}
The SmartCGMS concept application compiled as a \gls{wasm} module was extended to create simulation of a diabetic patient's blood glucose levels running on the web. Currently, it is deployed only locally.

The demo webpage was modified to allow input of meals, insulin boluses, and basal rate (simulated by small bolus doses). Each event sent to the filter chain advances the simulation time by 5 minutes. The filter chain configuration can be edited to modify the parameters of the filters or the model. Additionally, the parameters can be saved to a file from which they can be loaded. The file is stored in a virtual file system created by Emscripten. Multiple files can be created. This allows us to use filters that require files (e.g., log filter). However, the files stored in the Emscripten virtual file system are only temporary and are deleted when the webpage is reloaded. To maintain the content of the files, it needs to be copied when the simulation is over.
\newpage
The model is managed by a signal generator filter. This filter is required when configuring the filter chain in the demo. Another required filter is the data visualization filter that sends the events' information back to the JavaScript code to update the graph. Additional filters can be added to the filter chain.

The SmartCGMS web demo supports two models: Samadi model based on \parencite{samadi} and S2013 model based on \parencite{uvapadova}. The models can be changed just by modifying the model's \gls{guid} in the configuration.