diff --git a/.gitignore b/.gitignore
index 051810d3f334d430727a431c6daba6ae1a37e196..a15b9233fb1eaf13a108d3a161c2d72f9c52a510 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,10 @@
 # Build files
 build
 cmake-build-debug
-docs
+
+# Documentation output
+/docs/html
+/docs/latex
 
 # Dump and continuous integration files
 *.dump
@@ -74,4 +77,4 @@ __pycache__
 .idea/**/markdown-*
 
 # IDEs
-.vscode
\ No newline at end of file
+.vscode
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7c7becceea2926b617fdd2632e9fa20ce5d4cae4..0b3ef569bb6f779875aacc94788e471b2e836135 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -72,10 +72,10 @@ doxygen:
   stage: analyze
   script:
     - cd $CI_PROJECT_DIR
-    - doxygen doxygen.conf
+    - doxygen
   artifacts:
     paths:
-      - ./docs
+      - ./docs/html
 
 ikos:
   image: spacedot/ikos:3.0
@@ -120,10 +120,13 @@ pages:
   stage: deploy
   script:
     - mkdir .public
-    - cp -r ./{docs,gcovr,ikos-report,scan-build-html-report,clang-tidy-html-report,cppcheck-html-report} ./.public/
+    - cp -r ./docs/html ./.public/docs
+    - cp -r ./{gcovr,ikos-report,scan-build-html-report,clang-tidy-html-report,cppcheck-html-report} ./.public/
     - ls ./.public
     - find ./.public
     - mv .public public
+  after_script:
+    - "echo Base page for this branch: ${CI_PAGES_URL}"
   artifacts:
     paths:
       - public # Upload the resulting website
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 5d89f392d3d1e9e841f887a9f80e9c4d6350792f..0000000000000000000000000000000000000000
--- a/Dockerfile
+++ /dev/null
@@ -1,38 +0,0 @@
-# This is the Dockerfile for the lightspot21/acubesat-ci:latest
-# Docker image used at the pipeline. Please take care to generate 
-# and push a new image to the lightspot21/acubesat-ci repo every 
-# 1-2 weeks in order to ensure that the tools are at the latest version.
-# 
-# P.S. Tag properly your images with --tag lightspot21/acubesat-ci when
-# building.
-
-FROM alpine:latest
-
-# Set a new work directory. DO NOT DELETE THE LINE BELOW
-WORKDIR /root/
-
-# Set up clang-tidy version 8
-RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" \
-    >> /etc/apk/repositories && apk update && \
-    apk add --no-cache --virtual git-deps git && \
-    apk add --no-cache build-base cmake && \
-    apk add --no-cache python3 && \
-    git clone --depth=1 https://github.com/llvm/llvm-project.git -b release/8.x && \
-    cmake \
-    -DLLVM_ENABLE_PROJECTS="clang-tools-extra;clang" \
-    -DCMAKE_BUILD_TYPE=MinSizeRel \
-    -DLLVM_TARGETS_TO_BUILD="host" \
-    -G "Unix Makefiles" ./llvm-project/llvm && \
-    make -j$(nproc) clang-tidy && mv bin/clang-tidy /usr/bin/clang-tidy && \
-    rm -rf * && apk del git-deps
-
-# Update package lists and install cmake, cppcheck, doxygen, vera++, 
-# gcc and lcov with their dependencies
-RUN apk add --no-cache findutils python3-dev \
-    cppcheck doxygen vera++@testing lcov@testing
-
-# Install gcovr
-RUN python3 -m pip install gcovr
-
-# Start a new shell
-ENTRYPOINT ["/bin/sh", "-c"]
diff --git a/doxygen.conf b/Doxyfile
similarity index 99%
rename from doxygen.conf
rename to Doxyfile
index a723c79ce42474d250494a18605c120eefa4f235..419b742a3ebf4acbc6929bfea78c59b610269b4d 100644
--- a/doxygen.conf
+++ b/Doxyfile
@@ -32,7 +32,7 @@ DOXYFILE_ENCODING      = UTF-8
 # title of most generated pages and in a few other places.
 # The default value is: My Project.
 
-PROJECT_NAME           = "ASAT CubeSat ECSS PUS Implementation"
+PROJECT_NAME           = "AcubeSAT ECSS PUS Implementation"
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number. This
 # could be handy for archiving the generated documentation or if some version
@@ -310,7 +310,7 @@ MARKDOWN_SUPPORT       = YES
 # Minimum value: 0, maximum value: 99, default value: 0.
 # This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
 
-TOC_INCLUDE_HEADINGS   = 0
+TOC_INCLUDE_HEADINGS   = 5
 
 # When enabled doxygen tries to link words that correspond to documented
 # classes, or namespaces to their corresponding documentation. Such a link can
@@ -703,7 +703,7 @@ FILE_VERSION_FILTER    =
 # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
 # tag is left empty.
 
-LAYOUT_FILE            =
+LAYOUT_FILE            = docs/DoxygenLayout.xml
 
 # The CITE_BIB_FILES tag can be used to specify one or more bib files containing
 # the reference definitions. This must be a list of .bib files. The .bib
@@ -790,7 +790,7 @@ WARN_LOGFILE           =
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = README.md inc/ src/ test/Services/ServiceTests.hpp
+INPUT                  = docs/ inc/ src/ test/Services/ServiceTests.hpp
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -889,7 +889,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       =
+EXCLUDE_PATTERNS       = README.md
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -1008,7 +1008,7 @@ INLINE_SOURCES         = NO
 # Fortran comments will always remain visible.
 # The default value is: YES.
 
-STRIP_CODE_COMMENTS    = YES
+STRIP_CODE_COMMENTS    = NO
 
 # If the REFERENCED_BY_RELATION tag is set to YES then for each documented
 # function all documented functions referencing it will be listed.
@@ -1192,7 +1192,8 @@ HTML_STYLESHEET        =
 # list). For an example see the documentation.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_EXTRA_STYLESHEET  = "/root/doxygen-awesome-css/doxygen-awesome.css"
+HTML_EXTRA_STYLESHEET  = "../doxygen-awesome-css/doxygen-awesome.css"
+HTML_EXTRA_STYLESHEET  = "ci/page_style/doxygen_dark_theme/custom_dark_theme.css"
 
 # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the HTML output directory. Note
diff --git a/README.md b/README.md
index af9d33d97cdac80138dee87ff8c9d231010148fa..42ee0c7793aba48ee85df7c0fa41b5cb94d5d567 100644
--- a/README.md
+++ b/README.md
@@ -4,12 +4,33 @@ In this repository you can find the implementation of the ECSS services, based
 on the [ECSS-E-ST-70-41C](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/)
 standard.
 
+## Documentation
+You can read the complete documentation of this project at https://acubesat.gitlab.io/obc/ecss-services/docs/.
+This includes installation instructions, a usage guide, and detailed descriptions of all public functions and definitions.
+
 ## Directories
 - **ci**: GitLab CI configuration files
+- **docs**: Source code usage and development documentation
 - **inc**: All headers and libraries used in the code
 - **lib**: External libraries used in the code
 - **src**: All source files are included here
 - **test**: Unit test implementation
 
-## Documentation
-Full documentation about this project based on code comments is available at https://acubesat.gitlab.io/obc/ecss-services/docs/.
+## Implementation status
+
+| Service Type | Service Name                   | Implementation   |
+|--------------|--------------------------------|------------------|
+| ST[01]       | Request Verification           | Full             |
+| ST[03]       | Housekeeping                   | Partial          |
+| ST[04]       | Parameter Statistics Reporting | Partial          |
+| ST[05]       | Event Reporting                | Partial          |
+| ST[06]       | Memory Management              | Partial          |
+| ST[08]       | Function Management            | Full             |
+| ST[11]       | Time-based Scheduling          | Partial          |
+| ST[12]       | On-board Monitoring            | Work in progress |
+| ST[13]       | Large Packer Transfer          | Partial          |
+| ST[15]       | On-board Storage and Retrieval | Work in progress |
+| ST[17]       | Test                           | Partial          |
+| ST[19]       | Event-action                   | Partial          |
+| ST[20]       | Parameter Management           | Partial          |
+| ST[23]       | File Management                | Work in progress |
diff --git a/ci/vera.profile b/ci/vera.profile
deleted file mode 100644
index 2382359f944d16804f95c08abf35c78c0d758ae8..0000000000000000000000000000000000000000
--- a/ci/vera.profile
+++ /dev/null
@@ -1,25 +0,0 @@
-
-set rules {
-  F001
-  F002
-  L001
-  L003
-  L004
-  L005
-  L006
-  T001
-  T002
-  T004
-  T005
-  T006
-  T007
-  T008
-  T009
-  T010
-  T012
-  T015
-  T016
-  T017
-  T018
-  T019
-}
diff --git a/ci/vera.sh b/ci/vera.sh
deleted file mode 100755
index 2ece81da50bfefdefba08effef4bbadc3f7d415f..0000000000000000000000000000000000000000
--- a/ci/vera.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env bash
-
-#
-# Code style checks using vera++
-#
-# Usage:
-# $ ci/vera.sh
-#
-
-echo -e "\033[0;34mRunning vera++...\033[0m"
-
-cd "$(dirname "$0")/.."
-vera++ --error --parameter max-line-length=120 --profile custom \
-    `find src inc test -type f -regextype posix-egrep -regex '.*\.(cpp|hpp|c|h)' -not -wholename 'inc/Logger.hpp'`
diff --git a/docs/DoxygenLayout.xml b/docs/DoxygenLayout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b4ce28e401ca5d2f41336898ee7675542d0af31f
--- /dev/null
+++ b/docs/DoxygenLayout.xml
@@ -0,0 +1,39 @@
+<doxygenlayout version="1.0">
+  <!-- Generated by doxygen 1.8.17 -->
+  <!-- Navigation index tabs for HTML output -->
+  <navindex>
+    <tab type="mainpage" visible="yes" title=""/>
+    <tab type="pages" visible="yes" title="Pages" intro=""/>
+    <tab type="user" url="@ref Services" title="Services"/>
+    <tab type="modules" visible="yes" title="" intro=""/>
+    <tab type="namespaces" visible="yes" title="">
+      <tab type="namespacelist" visible="yes" title="" intro=""/>
+      <tab type="namespacemembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="interfaces" visible="yes" title="">
+      <tab type="interfacelist" visible="yes" title="" intro=""/>
+      <tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
+      <tab type="interfacehierarchy" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="classes" visible="yes" title="">
+      <tab type="classlist" visible="yes" title="" intro=""/>
+      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
+      <tab type="hierarchy" visible="yes" title="" intro=""/>
+      <tab type="classmembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="structs" visible="yes" title="">
+      <tab type="structlist" visible="yes" title="" intro=""/>
+      <tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
+    </tab>
+    <tab type="exceptions" visible="yes" title="">
+      <tab type="exceptionlist" visible="yes" title="" intro=""/>
+      <tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
+      <tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="files" visible="yes" title="">
+      <tab type="filelist" visible="yes" title="" intro=""/>
+      <tab type="globals" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="examples" visible="yes" title="" intro=""/>
+  </navindex>
+</doxygenlayout>
diff --git a/docs/design.md b/docs/design.md
new file mode 100644
index 0000000000000000000000000000000000000000..e08bea1267c2f1c192cb9c9aaab9a8d00467b7cc
--- /dev/null
+++ b/docs/design.md
@@ -0,0 +1,115 @@
+# Design
+
+@tableofcontents
+
+The main building block of this library are the @ref Services and the @ref Message.
+
+@dot
+digraph G {
+  rankdir=LR;
+
+  space [shape=box,label="Spacecraft"]
+  ground [shape=box,label="Ground Station"]
+
+  space:se -> ground:sw [label="Response (TM)",color="#039be5"]
+  ground:nw -> space:ne  [label="Request (TC)",color="#f4511e"]
+}
+@enddot
+
+Each Service is represented by a class. All Services reside inside the @ref ServicePool. Messages handle Telecommands
+and Telemetry in the form of @ref Message "Messages". A Message represents a _Space Packet_, as defined by [CCSDS
+133.0-B-2](https://public.ccsds.org/Pubs/133x0b2e1.pdf). Messages are managed and distributed by the @ref MessageParser class.
+
+## Reading and Writing Messages
+
+The Message is the simplest unit of information that is transferred between space and ground. A Message contains its
+payload data in a _binary string_ format, combined by some essential header information.
+
+As the message data is in a binary format, special functions have been written to facilitate reading from and writing to
+the Message:
+```cpp
+// Reading data
+message.readUint32();
+message.readFloat();
+
+// Writing data
+message.appendUint32();
+message.appendFloat();
+
+// You can also use templated functions, when the type is obvious and unambiguous
+message.append<int16_t>(10);
+message.append(someVariable);
+```
+
+You can visit @ref Message for a complete description of all functions available for data manipulation.
+
+You will typically need access to `.read()` and `.append()` functions only when developing a Service. Any manipulation
+of Messages will typically be done only inside the Service classes.
+
+## The Lifetime of a Message
+@dot
+digraph H {
+    rankdir=LR
+
+    Message [label="TM Message",URL="@ref Message",shape=box,style=filled,color="#039be5"]
+    D [label="storeMessage()",fontname="monospace"]
+
+    subgraph cluster_0 {
+        style=filled
+        color=lightgrey
+        node [style=filled,color=white]
+
+        A [label="@ref MessageParser",fontname="monospace"]
+        B [label="Service::function()",fontname="monospace"]
+
+        A -> B
+
+        label = "Telemetry (TM) processing";
+    }
+
+    subgraph cluster_1 {
+        style=filled
+        color=lightgrey
+        node [style=filled,color=white]
+
+        C [label="Service::function()",fontname="monospace"]
+        TCMessage [label="TC Message",shape=box,style=filled,color="#f4511e"]
+
+        C -> TCMessage
+
+        label = "Telecommand (TC) generation";
+    }
+
+    Message -> A
+    B -> C
+    TCMessage -> D
+}
+@enddot
+
+ecss-services can receive and transmit ECSS messages from and to a ground segment or other subsystems. The codebase is
+responsible for the parsing, execution and responses to those messages. Additionally, it provides the tools to tailor
+the actions of each service to your subsystem.
+
+### Message reception
+
+When any Telemetry is received, it is first sent in raw format to the @ref MessageParser class. The MessageParser is
+responsible for reading the headers of the data, converting it to a @ref Message class, and sending it to the relevant
+service.
+
+Inside every Service, each TM message type is tied to a single function that receives the Message as an argument. This
+function is responsible for parsing and starting the execution of the contents of the message. It will also generate the
+relevant TC, if needed.
+
+### Message generation
+
+After creating a Message and populating it with data, it can then be sent on its way. The @ref Service::storeMessage
+function is responsible for propagating the TC message to the next layer.
+
+The next step can be:
+- Storage of the message for later retransmission (ST[15] service)
+- Immediate transmission of the message to its recipient (e.g. via an antenna, ST[14] service)
+- Transmission of the message to other observers (e.g. logging for debugging purposes)
+
+Sometimes, you may want to generate TC without any external stimulus. For example, when an event occurs (e.g. antenna
+deployed), you will want to notify the ecss-services library to generate the corresponding TC and take any other actions
+required (e.g. event-action definitions). To generate arbitrary TC, just call the relevant functions on each Service class.
diff --git a/docs/ecss_overview.md b/docs/ecss_overview.md
new file mode 100644
index 0000000000000000000000000000000000000000..82e0011181d26b321d3163e2f5bb1d947e97eb54
--- /dev/null
+++ b/docs/ecss_overview.md
@@ -0,0 +1,203 @@
+# Overview to the PUS standard {#pus-overview}
+
+@tableofcontents
+
+The `ecss-services` library implements the ECSS-E-ST-70-41C **Telemetry and telecommand packet utilization** standard,
+released by the European Cooperation for Space Standardization. The complete text of the standard is
+[available after a free registration](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/).
+This page summarises the core concepts of the standard, and how it can be useful to a typical space mission.
+
+The ECSS-E-ST-70-41C standard (also called **Packet Utilisation Standard**, or **PUS** for short) lists a number of
+**services** that a spacecraft can support. These services define basic operational functions of a spacecraft, such as
+file storage, statistics generation, responding to events and many others. Each Service is also accompanied with
+different Message types. These messages can be:
+- **Telecommand (TC) requests**: Messages from a Ground Station to the Spacecraft. These messages often request specific
+  information, or command the spacecraft to take specific actions.
+- **Telemetry (TM) reports**: These can be responses to other commands, or they can inform the Ground Station about
+  interesting events and information happening on the spacecraft.
+
+The standard clearly defines the **byte-level structure** of each Message, as well as the **capabilities** that each
+  Service provides.
+
+## Important entities
+A few entities defined in ECSS-E-ST-70-41C are used throughout the standard and are useful to keep in mind:
+1. **@ref Parameter "Parameters"**. A parameter is a value (often numerical) that represents a small piece of data which
+   can be sent to or received from the satellite. Parameters can represent sensor outputs, configuration values, status
+   indicators, or everything else.
+
+   Parameters are mainly handled by the @ref ParameterService, but they are regularly used throughout the code when
+   dealing with satellite data.
+
+   Parameters can be numbers of different types, strings or (rarely) more complex entities.
+2. **Events**. Events represent expected or unexpected occurences on the spacecraft.
+
+   The @ref EventReportService is mainly responsible for management of on-board events. Other services provide the
+   capability of generating or responding to on-board events.
+
+3. **Application Processes** (AP). An Application Process is any physical (hardware) or logical (software) entity that
+   can handle PUS messages.
+
+   In most cases, an Application Process will be a single microcontroller or subsystem. For example, the
+   <span title="On-Board Computer">OBC</span>, <span title="Attitude Determination and Control Subsystem">ADCS</span> and Ground
+   Station may be different Application Processes.
+
+   Typically, a message will have an AP as a source, and another AP as its destination. For example, if the Ground
+   Station wants to send a message to the OBC, it can send a Telecommand where the OBC Application Process is listed as
+   the destination.
+
+   @todo Application Process handling is not yet implemented in this library. See
+   [#55](https://gitlab.com/acubesat/obc/ecss-services/-/issues/55).
+
+## The services
+
+This section provides a very short overview of each ECSS service, and how it can be typically used in a space mission.
+
+All services are designed to be **highly configurable during flight**. While they can have a pre-defined configuration
+at launch, the Ground Station can send simple telecommands (TC) to modify the services.
+
+The standard aptly defines itself as a _"menu"_ from which services are chosen. The following services do not need to be
+fully implemented for each mission, but need to be _tailored_ according to the requirements and needs of the spacecraft
+and its environment.
+
+Each service is further divided into some **subservices** that are logical groupings of a service's functionality. A
+large space mission may split every subservice into different parts of the hardware. However, this implementation _makes
+no distinction between subservices_.
+
+<b>`ST[01]`: Request verification</b>
+
+Provides acknowledgement or failure reports for executed commands. This service essentially informs the operators about
+the status of TCs sent to the spacecraft, and reports any occurred errors during parsing or execution.
+
+See @ref #error-handling for more information regarding error handling on this library.
+
+<b>`ST[02]`: Device access</b>
+
+Allows toggling, controlling and configuring on-board peripherals that rely on simple protocols to communicate
+(such as I2C).
+
+<b>`ST[03]`: Housekeeping</b>
+
+Produces periodic TM reports with values of parameters. This service is the one providing the most essential information
+about the status of the spacecraft.
+
+ST[03] is also highly configurable during flight. For example, it allows:
+- Selecting which parameters we want to be periodically transmitted
+- How often the parameters should be transmitted
+- Enabling/disabling specific types of periodic reports at will
+
+<b>`ST[04]`: Parameter statistics reporting</b>
+
+Allows reporting statistics (min, max, mean, standard deviation) for specific parameters over specified durations. This
+is a data-efficient alternative to the `ST[03]` housekeeping service.
+
+<b>`ST[05]`: Event reporting</b>
+
+Generates reports when notable occurrences take place on-board, such as:
+
+- Autonomous on-board actions
+- Detected failures or anomalies
+- Predefined steps during an operation
+
+<b>`ST[06]`: Memory management</b>
+
+Allows writing and reading directly from an on-board memory unit. This can be useful for debugging and investigative
+purposes, fetching mission data, or uploading new software to the spacecraft's memories. The service also allows
+downlinking and uplinking files in a file system.
+
+<b>`ST[08]`: Function management</b>
+
+Provides the capability of running predefined actions that can receive further parameters. These actions can correspond
+to payload, platform, or any other functionality.
+
+<b>`ST[09]`: Time management</b>
+
+Allows periodic reporting of the current spacecraft time for observability and correlation purposes.
+
+<b>`ST[11]`: Time-based scheduling</b>
+
+Allows the operators to <b>"time-tag"</b> telecommands for execution at future timestamps, instead of immediately. Its use
+is essential when communication with your spacecraft is not guaranteed for the entirety of its orbit.
+
+This is one of the most complicated services to use, as it allows complex functionality such as:
+- Running a command after some duration of time
+- Running a command at a specified time
+- Running a command after successful execution of another command
+- Running a command only if another command fails
+
+<b>`ST[12]`: On-board monitoring</b>
+
+This service allows checking parameter values to ensure that they remain within configurable limits. Whenever a
+violation occurs, an `ST[05]` event can be optionally generated for further processing.
+
+<b>`ST[13]`: Large packet transfer</b>
+
+Provides a method of message segmentation, for message payloads that are too large to fit within the maximum allowed
+length for TC or TM.
+
+The maximum limits are usually imposed by the lower communication layers. For example, the Communications subsystem of a
+satellite may use a transceiver that can only send packets up to 64 bytes long.
+
+<b>`ST[14]`: Real-time forwarding control</b>
+
+This service is responsible of controlling which types of generated reports are immediately transmitted to the ground.
+
+<b>`ST[15]`: On-board storage and retrieval</b>
+
+Allows storing generated TM reports on-board.
+
+If your spacecraft does not have constant communication with the Ground Station (e.g. a low-earth orbit satellite), it
+will be necessary to store all messages until they can be downlinked safely. The ST[15] service can be used to:
+- Downlink all packets that haven't yet been transmitted
+- Filter packets by their type
+- Filter packets by the time of their creation
+
+<b>`ST[17]`: Test</b>
+
+Allows performing on-board connection checks, similar to "pinging" a machine and asking if it is alive.
+
+<b>`ST[18]`: On-board operations procedure</b>
+
+Allows loading, controlling (start, suspend, resume, abort) and configuring On-Board Control Procedures, which are
+sequences of commands written in an application-specific language.
+
+<b>`ST[19]`: Event-action</b>
+
+Provides the capability of automatically executing arbitrary actions when an `ST[05]` event is triggered. This service
+can be an essential component when planning the autonomous functionalities of a spacecraft.
+
+<b>`ST[20]`: On-board parameter management</b>
+
+Provides the capability of reading and setting on-board parameters.
+
+<b>`ST[21]`: Request sequencing</b>
+
+Allows operators to load series of TCs to be executed in a sequential order.
+
+<b>`ST[22]`: Position-based scheduling</b>
+
+Provides the capability of executing TCs when the spacecraft reaches a specific point in its orbit.
+
+<b>`ST[23]`: File management</b>
+
+Provides the capability of managing on-board file systems, with functions such as *copy*, *move*, *delete*, or *create
+directory*.
+
+The capability also exists to define _custom_ services and message types, if needed for each mission.
+
+## Trivia
+- Version C of the standard contains 656 pages, often filled with verbose requirements and difficult definitions. Every
+  requirement is identified by its requirement ID. [Version
+  A](https://ecss.nl/standard/ecss-e-70-41a-ground-systems-and-operations-telemetry-and-telecommand-packet-utilization/)
+  contains a simpler but outdated and less rigorous version of the standard.
+- This standard is not optimised for heavy communication, e.g. real-time audio/video, large files, etc. Other protocols
+  and solutions can be used for this purpose (e.g. [CFDP](https://public.ccsds.org/Pubs/720x1g4.pdf)).
+- While the standard is mainly designed for ground-space communication, it can theoretically be used to coordinate
+  communication between different subsytems onboard a spacecraft.
+- This repository _does not implement the entire standard_. A subset has been selected that should be useful to our
+  mission, or to any CubeSat that requires some basic functionality. ECSS characteristically mentions that this standard
+  serves as a "menu" from which to select all relevant services.
+- While all services are designed in a modular manner, there are often various relationships between them (e.g. ST[05]
+  event reporting — ST[19] event-action). Additionally, some services provide _observable_ parameters (e.g. ST[23] may
+  provide the available memory space as an observable)
+- Each service can be implemented by a single microcontroller in a spacecraft, or by multiple different units. The
+  standard does not define any implementation restrictions on this regard.
diff --git a/docs/error_handling.md b/docs/error_handling.md
new file mode 100644
index 0000000000000000000000000000000000000000..511b361b950e9c6a44677bbe8cb8a2aea1104dc2
--- /dev/null
+++ b/docs/error_handling.md
@@ -0,0 +1,140 @@
+# Error Handling {#error_handling}
+
+@tableofcontents
+
+Errors can show up in almost any location on this library, for example:
+- When an incorrect Message is received, containing invalid information (due to a faulty channel or operator error)
+- When an unexpected bug occurs
+- When radiation or a hardware issue leads to an unexpected software state
+
+This library incorporates an error handling framework to allow proper identification and recovery from various errors,
+without violating the performance and memory constraints of an embedded system.
+
+As [exceptions are not used](docs/writing_code.md), this library uses a slightly different approach to testing and
+reporting errors from what is standard in C++.
+
+@note Errors do not have to be fatal or lead to a loss of the subsystem. Most errors should be recoverable with minimal impact
+to the rest of the system.
+
+## The ErrorHandler class
+
+The processing of errors in the `ecss-services` library is managed by the @ref ErrorHandler class. The ErrorHandler
+provides a number of convenience functions to report any errors that occur using a single line of code (demonstrated below).
+
+In order to convey the most information using the minimal amount of data, all **error types** are encoded into different
+enumerations inside the @ref ErrorHandler.
+
+When deemed necessary, the developer can add additional **auxiliary data** to each error, to provide more observability
+to the ground station if needed.
+
+@todo Auxiliary data not implemented yet, see [#28](https://gitlab.com/acubesat/obc/ecss-services/-/issues/28)
+
+### The ST[01] service
+
+The `ST[01] service request verification` service is responsible for generating error notifications when an issue is
+found in a **received Telemetry message**. It does not cover errors generated by internal functions.
+
+For example, the following incidents **will** trigger an ST[01] error:
+- Ground Station asks for Parameter #205, but Parameter #205 does not exist
+- Ground Station asks to disable Temperature Sensor, but Temperature Sensor is already disabled
+- Ground Station sends a corrupted message that makes no sense
+
+The following incidents **will not** trigger an ST[01] error:
+- A division by zero happens
+- A loop that should run 5 times runs 101 times
+- A temperature sensor experiences a failure
+
+Any ST[01] failure report (i.e. a TM message generated by ST[01] to inform us about a problem that was caused by a TC
+message) is tied to **the TM that caused it**. That means that every ST[01] report contains information about the
+problematic TM, such as its packet type and counter. The report also contains the **error type** and any **auxiliary
+data** available for this error.
+
+To report an error tied to a Message, you can use @ref ErrorHandler::reportError.
+```cpp
+ErrorHandler::reportError(message, errorType);
+```
+
+You can also use convenience functions like @ref Message::assertType, @ref Message::assertTM, or @ref Message::assertTC.
+These will check if your Message is of a specific type, and call `reportError` on their own if it is not.
+
+### Internal errors
+
+Errors that are not tied to a specific TC and are caused independently by a microcontroller are termed _internal
+errors_. While they are still managed by the @ref ErrorHandler, they are not part of the standard.
+
+To report an internal error, you can use @ref ErrorHandler::reportInternalError.
+```cpp
+ErrorHandler::reportInternalError(errorType);
+```
+
+You can also use the convenience @ref ASSERT_INTERNAL macro, which checks if a condition is true, and calls @ref
+ErrorHandler::reportInternalError automatically if not:
+```cpp
+ASSERT_INTERNAL(5 > 3, ErrorHandler::MathematicsIsBroken);
+```
+
+## Function results
+An important question that comes to mind when disabling extensions is how errors are propagated through the code. When a
+function is executed, it must be clear when the result of the function is correct and when it is not. Additionally, any
+parts of the code that depend on a successful result may need to avoid being executed when an error occurs.
+
+While there are different available approaches to failure propagation (e.g.
+[errno](https://www.tutorialspoint.com/cprogramming/c_error_handling.htm), error pointers as arguments etc.), the
+`ecss-services` library indicates the error in the **return value** of each function, through the @ref Result class.
+
+The @ref Result class can contain **either**:
+- A successful result (e.g. an `int` or a `string` or a @ref Parameter), or
+- An error, explaining why it failed to find a result
+
+By calling the relevant functions of a @ref Result, the user can access its contents on success, or abort the operation
+in case of failure.
+
+### Example usage
+
+The simplest usage of a `Result` might be as follows:
+```cpp
+Result<T,E> something = ...
+
+if (something.error()) {
+    // No! An error happened! We cannot continue!
+    return;
+}
+
+// No errors, we can happily use the result
+something->coolFunction();
+```
+
+### Error propagation
+The @ref Result class offers many convenience functions to aid in common, yet complex situations.
+
+For example, we may want a function that takes the average of many parameters. However, this function will fail if one
+of those parameters does not exist.
+
+```cpp
+Result<float, Error> getAverage(ParameterArray parameterIds) {
+    // Don't allow entering an empty array, by throwing the relevant error
+    if (parameterIds.empty()) {
+        // Error automatically gets converted to Result<float, Error>
+        return ErrorHandler::EmptyInputError;
+    }
+
+    float sum = 0;
+
+    for (auto parameterId : parameterIds) {
+        // You should use `auto` here. We keep the full type for demonstration purposes
+        Result<Parameter, Error> parameter = ParameterService::getParameterById(parameterId);
+
+        if (parameter.error()) {
+            // Result<anything, Error> automatically gets converted to Result<float, Error>
+            return parameter;
+        }
+
+        sum += parameter.getValue();
+    }
+
+    // float automatically gets converted to Result<float, Error>
+    return sum / parameterIds.count();
+}
+```
+
+@todo Result class not implemented and not used. See [#134](https://gitlab.com/acubesat/obc/ecss-services/-/issues/134)
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..ace2f3aa86c7a9a4c82171ec17e7de57ac7ee955
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,23 @@
+# AcubeSAT ECSS Services {#mainpage}
+
+This repository contains the implementation of the [ECSS-E-ST-70-41C](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/) standard, as used in the AcubeSAT mission.
+
+## Installation
+
+Read [Installation](docs/installation.md) to see how to download, compile and install ecss-services.
+
+Read [Usage with Microcontroller](docs/usage_with_microcontroller.md) to see how to integrate ecss-services with your
+satellite or embedded system.
+
+## How to read this documentation
+
+This documentation contains the technical documentation for the implementation of the ECSS documentation. For a description of the requirements see [version A](https://ecss.nl/standard/ecss-e-70-41a-ground-systems-and-operations-telemetry-and-telecommand-packet-utilization/) and [version C](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/) of the standard.
+
+To get into the documentation you can read:
+1. A list of [pages](pages.html) that contain generic information on the philosophy, design and usage of the services
+2. A list of [modules](modules.html) that group interesting functionality with the relevant instructions
+3. A list of [classes](annotated.html) that contain the most interesting entities and objects in the code
+4. A list of [namespaces](namespaces.html) that contain grouped utility functions or variables
+
+A good starting point would be the @ref Services module. You can browse through each ECSS Service based on the functionality you desire.
+
diff --git a/docs/installation.md b/docs/installation.md
new file mode 100644
index 0000000000000000000000000000000000000000..d6f5916ba8842160b8f7c21054ed8e860c86e0d9
--- /dev/null
+++ b/docs/installation.md
@@ -0,0 +1,68 @@
+# Installation
+
+@tableofcontents
+
+The ECSS Services library was is developed and tested on Linux. It is possible to use Mac OS or Windows, if the relevant
+tools are installed.
+
+## Required software {#required-software}
+Before getting started, you will need to make sure that you have the required compilation tools installed. We use the
+[CMake](https://cmake.org/) build system for all the instrumentation required for compiling.
+
+On Debian-based systems, a command like the following should suffice:
+```bash
+sudo apt install git cmake make binutils build-essential
+```
+
+If you want to run the **optional tools**, including documentation generators and code checkers, you will need to
+install them as well:
+```bash
+sudo apt install doxygen clang-tidy clang-format gcovr lcov cppcheck
+```
+
+## Compiling {#compiling}
+To download and build the ecss-services repo, use the following terminal commands:
+
+1. Clone the repository, along with its submodules
+   ```bash
+   git clone --recursive https://gitlab.com/acubesat/obc/ecss-services.git
+   ```
+
+2. Create the `build` directory. This is where the executables and outputs will be stored.
+   ```bash
+   cd ecss-services
+   mkdir build
+   ```
+
+3. Create the CMake project and Makefile
+   ```bash
+   cmake ..
+   ```
+
+4. Run the build!
+   ```bash
+   make -j${nproc}
+   ```
+
+You will be able to run the `./ecss-services` script to see how the output of the services may look like, or `./tests`
+to run some unit tests and verify that the code works correctly.
+
+## Other tasks {#other}
+
+Apart from compiling the services, you can also generate other outputs if you want.
+
+### Integrating with your code {#integrating}
+While ecss-services can run independently, the repo is built as a library. Follow the instructions in
+[Usage with a microcontroller](docs/usage_with_microcontroller.md) to integrate with your space or ground segment code.
+
+
+### Creating the documentation {#documentation}
+To create the documentation files, make sure you have `doxygen` installed. Afterwords, you can just run from the root
+directory:
+```bash
+doxygen
+```
+
+### Running static analysis scripts {#static-analysis}
+To run the static analysis scripts, you can open `.gitlab-ci.yml` and find the script you are interested in. Make sure
+to have the relevant static analysis tool installed beforehand!
diff --git a/docs/protocols.md b/docs/protocols.md
new file mode 100644
index 0000000000000000000000000000000000000000..dc64877bd34f34bd423a6cf4667e27c9f4e56fb4
--- /dev/null
+++ b/docs/protocols.md
@@ -0,0 +1,42 @@
+# Protocols and Standards
+
+@tableofcontents
+
+This library implements the application layer as defined in the following protocols:
+- [ECSS-E-ST-70-41C](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/)
+  (Packet Utilisation Standard)
+- [CCSDS 133.0-B-2](https://public.ccsds.org/Pubs/133x0b2e1.pdf) (Space Packet)
+
+<table>
+<tr>
+<td colspan="4" align="center">Space Packet</td>
+</tr>
+<tr>
+<td colspan="1" align="center">Space Packet Primary Header</td>
+<td colspan="3" align="center">Packet Data Field</td>
+</tr>
+<tr>
+<td colspan="1" align="center">Space Packet Primary Header</td>
+<td colspan="1" align="center">ECSS Secondary Header</td>
+<td colspan="1" align="center">ECSS Data Field</td>
+<td colspan="1" align="center">ECSS Error Control</td>
+</tr>
+</table>
+
+These protocols are supposed to be encapsulated in protocols representing the higher layers. For example, an RF message
+may be placed in a CCSDS 132.0-B-3 frame, while a message transmitted via wire may be placed inside a CAN bus frame.
+The user of this library must specify how a message is received and transmitted (see @ref usage-mcu).
+
+The headers defined by the different protocols define different attributes of the message, such as:
+- Its length
+- Its source
+- Its destination
+- A counter to identify lost messages
+- The time it was generated
+- Whether a response is expected on success
+- The number of the ECSS service of the message
+
+The **error control** field embeds an **Error-Detecting Code** to investigate if the message was transmitted and
+received correctly, and was not corrupted by faults in the communication channel. It is managed by @ref
+Message::finalize.
+
diff --git a/docs/usage_with_microcontroller.md b/docs/usage_with_microcontroller.md
new file mode 100644
index 0000000000000000000000000000000000000000..05f09b6f1f8e3e714846e0a0eab2e618b4d81c35
--- /dev/null
+++ b/docs/usage_with_microcontroller.md
@@ -0,0 +1,172 @@
+# Usage with a microcontroller {#usage-mcu}
+
+@tableofcontents
+
+ecss-services relies on many functions that may not be readily available to a microcontroller, such as printing,
+getting the time, transmitting packets etc. That's why you will have to implement a few simple functions by yourself
+when porting this library to a microcontroller.
+
+The library is also attempting to be modular enough to support the needs of your own spacecraft. After setting it up,
+you will be able to specify your own parameters, functions, events, and other definitions. All limits and numeric
+constants are not hard-coded, but can be modified in @ref ECSSDefinitions.
+
+@attention The ecss-services repository is not designed to be used as a static or dynamic library. Due to the embedded
+nature of the project, ecss-services may have a different binary output for every different usecase. You will need to
+compile this library independently for different projects.
+
+## Examples
+
+Some people have already integrated this library with their own code:
+- [AcubeSAT OBC Software](https://gitlab.com/acubesat/obc/obc-software), integration with ATSAMV71Q21 and FreeRTOS
+- [AcubeSAT FDIR Thesis](https://github.com/kongr45gpen/fdir-demo), integration with ATSAMV71Q21 and FreeRTOS
+- [AcubeSAT OBC Mockup](https://gitlab.com/acubesat/obc/mockup-4), integration with STM32L4S9 and FreeRTOS
+
+## The Platform directory
+
+ecss-services declares some basic functions, but does not implement them. You, the user of this library, must write the
+code for these functions that will make them work on your platform.
+
+The `inc/Platform` and `src/Platform` directories contain some platform-specific code that has already been prepared.
+The **`x86`** subdirectory includes all the code necessary to run on a Linux platform, i.e. your computer. This code is
+only used when building for a desktop environment, and is not compiled when building for a microcontroller.
+
+## Integration with CMake
+
+While `ecss-services` is a typical C++ project, it is built and based around the [CMake build
+system](https://cmake.org/). If you are using CMake in your project, you can easily integrate `ecss-services` in your
+`CMakeLists.txt` file, just by adding these lines:
+
+```cmake
+# ecss-services include directories
+include_directories(lib/ecss-services/inc)
+include_directories(lib/ecss-services/inc/Platform/x86)
+include_directories(lib/ecss-services/lib/etl/include)
+include_directories(lib/ecss-services/lib/logger/inc)
+
+# Build ecss-services and link it to the project
+add_subdirectory(lib/ecss-services EXCLUDE_FROM_ALL)
+target_link_libraries(<project_name> common)
+```
+
+Assuming your project is called `<project_name>` and the library is installed in `lib/ecss-services`, the above lines
+will automatically compile ecss-services for you using the compiler applicable to your application, and link them to
+your project.
+
+## Functions to implement
+
+The following sections list and explain the functions that need to be implemented by library users. It is enough to
+place the function body inside a compiled `.cpp` file. Otherwise, the linker will show errors about undefined functions.
+
+For more details on the requirements, arguments and return values of each function, refer to their respective documentation.
+
+### Logger
+
+The logger is responsible for outputting messages through a serial interface used for debugging purposes.
+
+You need to define the following function:
+```cpp
+void Logger::log(Logger::LogLevel level, etl::istring & message);
+```
+
+This function is responsible for getting a log level and log message, and outputting them through a serial port that can
+be inspected by the developers. It is suggested to add any extra information that is available, e.g. current time or
+execution thread.
+
+An example definition can be as follows:
+```cpp
+void Logger::log(Logger::LogLevel level, etl::istring &message) {
+    etl::string<20> time;
+    etl::to_string(MCU_Get_Time(), time);
+
+    etl::string<250> output;
+    output.append(time);
+    output.append(" ");
+    output.append(message);
+
+    MCU_Serial_Write(output);
+}
+```
+
+#### Setting the log level
+You will also need to set the **minimum log level** of your application by setting the relevant `LOGLEVEL` constants.
+
+For example, you can add this to your `CMakeLists.txt` to log all messages:
+```cmake
+add_compile_definitions(LOGLEVEL_TRACE)
+```
+
+For a list of all possible log levels, refer to the documentation of the Logger.
+
+@note If you want to have different log levels for different parts of your application, you can use [`target_compile_definitions`](https://cmake.org/cmake/help/latest/command/target_compile_definitions.html).
+
+@note All logs with a level lower than the specified one will not be compiled at all, and will not be included in any
+form in the resulting binary. This means that disabled log messages _will not_ have any negative impact on the
+performance and size of your program.
+
+### Message transmission
+
+Whenever PUS telemetry is generated, it needs to be transmitted or sent to a receiver. This is the responsibility of the
+@ref Service::storeMessage function.
+
+In this function, you can transmit the message via an antenna, send it through an interface for debugging, or both.
+
+An example definition can be as follows:
+```cpp
+void Service::storeMessage(Message& message) {
+	message.finalize();
+
+	MCU_Antenna_Transmit(message.data, message.dataSize);
+
+	LOG_DEBUG << "Just sent ST[" << static_cast<int>(message.serviceType) << "] message";
+}
+```
+
+### Error handling
+
+The @ref ErrorHandler::logError is responsible for logging errors for debugging purposes.
+
+@note Any generated errors are already transmitted to the ground segment via @ref Service::storeMessage. The @ref
+ErrorHandler::logError function is used strictly for debugging purposes, and can be left empty if desired.
+
+An example definition can be as follows:
+```cpp
+template <typename ErrorType>
+void ErrorHandler::logError(const Message& message, ErrorType errorType) {
+	LOG_ERROR << "Error in ["
+        << static_cast<uint16_t>(message.serviceType)
+        << ", " << static_cast<uint16_t>(message.messageType)
+        << "]: " << errorType;
+}
+
+template <typename ErrorType>
+void ErrorHandler::logError(ErrorType errorType) {
+	LOG_ERROR << "Error: " << errorType;
+}
+```
+
+## Service initialisation
+
+Platform-specific code also gives a chance to every Service to use pre-initialised entities (e.g. parameters, monitoring
+definitions etc.) during boot. The following functions are called at initialisation:
+1. @ref ParameterService::initializeParameterMap
+
+An example definition can be as follows:
+```cpp
+Parameter<uint8_t> parameter1(200);
+Parameter<uint8_t> parameter2(150);
+Parameter<uint8_t> parameter3(100);
+
+void ParameterService::initializeParameterMap() {
+	parameters = {{0, parameter1}, {1, parameter2}, {2, parameter3}};
+}
+```
+
+## Receiving messages
+
+After making sure that your code compiles, you need to provide a way of feeding received TC into the services. This can
+be done easily:
+```cpp
+MessageParser::parse(string, size);
+```
+
+You can use the rest of the @ref MessageParser functions if you have a more specific use-case.
diff --git a/docs/writing_code.md b/docs/writing_code.md
new file mode 100644
index 0000000000000000000000000000000000000000..57b878c6fd70f89de405b7d7ed4b9472746741e4
--- /dev/null
+++ b/docs/writing_code.md
@@ -0,0 +1,91 @@
+# Writing code
+@tableofcontents
+
+The ECSS-Services repository is based on C++17 and is compiled by gcc. The nature of the project means that there are a number of limitations and guidelines that need to be followed before code is accepted to the default branch.
+
+## Restrictions {#restrictions}
+
+This repository contains mission-critical software that is destined for use in space. As such, a number of restrictions are in place to ensure high performance, bounded memory and determinism.
+
+The following C++ features are **forbidden** from use in flight-ready software:
+1. **Dynamic memory allocation**.
+
+   This prohibits use of `malloc`/`free`, `new`/`delete` and almost most `std::` containers.
+2. **Run-Time Type Inference** (RTTI).
+
+   This prohibits use of `dynamic_cast`, `typeid` and `std::type_info`.
+3. **Exceptions**
+4. **Multiple inheritance**
+5. Some features only available in [hosted implementations](https://en.cppreference.com/w/cpp/freestanding).
+
+   If a C++ or compiler feature is not available in a bare-metal microcontroller, then it cannot be used in this repository.
+
+   This prohibits use of libraries such as `<ctime>`, `<pthreads>`, `<iostream>` and others.
+
+@see [DDJF_OBSW](https://gitlab.com/acubesat/documentation/cdr-public/-/blob/master/DDJF/DDJF_OBSW.pdf)
+
+There are no strict requirements about compiler portability: ecss-services is built around modern versions of `gcc` and
+`clang`. While no unexpected behaviour mush be invoked, and the code must remain portable across different
+architectures, we occasionally use compiler-specific features to aid performance or memory management.
+
+## Code standards {#seandards}
+
+The ECSS-Services repository uses a number of tools to perform static code analysis, which are part of the automated CI/CD pipeline.
+
+Due to the lack of available free static analysis tools for embedded standards, only the checks mentioned above are executed. However, performed static analysis checks and rules loosely follow the following guidelines:
+- [The Power of 10: Rules for Developing Safety-Critical Code](https://spinroot.com/gerard/pdf/P10.pdf)
+- [MISRA C++](https://www.misra.org.uk/misra-c-plus-plus/)
+- [Joint Strike Fighter C++ Coding Standards](https://www.stroustrup.com/JSF-AV-rules.pdf)
+- [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
+
+## Code style {#code-style}
+
+This repository typically follows the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) with the following notable modifications:
+1. The code is indented using **tabs**
+2. A soft column limit of `120` characters is followed
+3. Variable names are in `camelCase`
+4. Constant names are in `PascalCase`
+
+Code style can be enforced automatically:
+- By using the CLion _Reformat Code_ function
+- By using [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) and the accompanying `.clang-format` file.  \
+  You can use the `ci/clang-format.sh` script for automated code reformatting across the repository.
+
+Note that code style is not enforced authoritatively; sometimes deviations may exist between the two tools and the current code. Occasional deviations are accepted if needed for better readability and maintainability.
+
+## Documentation {#documentation}
+
+We use [Doxygen](https://www.doxygen.nl/index.html) to document our code and its interfaces. All classes, functions and most variables should be documented using doxygen.
+
+We use javadoc-style comments, for example:
+```cpp
+/**
+ * This class represents an object that exists.
+ *
+ * Represents a [physical object](https://en.wikipedia.org/wiki/Thing) and its location in our universe.
+ * Coordinates are given according to XYZ. This is similar to the @ref Item class, but implemented dynamically.
+ *
+ * @warning Functions in this class are not re-entrant and should be used carefully when combined with an RTOS.
+ */
+class Something
+```
+
+## Resources {#resources}
+
+Contributing to ecss-services requires using modern C++ that is not often seen in the wild. There are various resources
+available online, covering beginner to advanced topics, such as:
+1. Introductory
+   - [A Tour of C++](https://isocpp.org/tour)
+   - [learncpp.com](https://www.learncpp.com/)
+   - [Introduction to C++, MIT 6.096](https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-096-introduction-to-c-january-iap-2011/index.htm)
+   - [Wikiversity Introduction to C++](https://en.wikiversity.org/wiki/C%2B%2B/Introduction)
+3. Advanced
+   - [C++ Notes for Professionals](https://goalkicker.com/CPlusPlusBook/)
+4. Specific to modern C++
+   - [Modern C++ Tutorial: C++11/14/17/20 On the Fly](https://github.com/changkun/modern-cpp-tutorial)
+   - [C++ Super-FAQ](https://isocpp.org/faq)
+   - [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
+5. References
+   - [cppreference.com](https://en.cppreference.com/w/), contains advanced descriptions of pretty much every feature of C++
+6. Tools
+   - [Compiler Explorer](https://godbolt.org/)
diff --git a/inc/Services/EventActionService.hpp b/inc/Services/EventActionService.hpp
index f0c33e1702a664a851ae91053d6e7cb579b575fd..6ed438d8f07834d475c6ada312d2c3ec8d1555d8 100644
--- a/inc/Services/EventActionService.hpp
+++ b/inc/Services/EventActionService.hpp
@@ -12,18 +12,18 @@
  * ECSS 8.19 && 6.19
  *
  * @ingroup Services
- * @note: Make sure to check the note in the addEventActionDefinition()
- * @note: A third variable was added, the eventActionDefinitionID. This was added for the purpose of identifying
+ * @note Make sure to check the note in the addEventActionDefinition()
+ * @note A third variable was added, the eventActionDefinitionID. This was added for the purpose of identifying
  * various eventActionDefinitions that correspond to the same eventDefinitionID. The goal is to have multiple actions
  * be executed when one event takes place. This defies the standard.
- * @note: The application ID was decided to be abolished as an identifier of the event-action
+ * @note The application ID was decided to be abolished as an identifier of the event-action
  * definition
- * @attention: Every event action definition ID should be different, regardless of the application ID
+ * @attention Every event action definition ID should be different, regardless of the application ID
  *
- * @todo: Since there are multiple actions per event and in delete/enable/disable functions are
+ * @todo Since there are multiple actions per event and in delete/enable/disable functions are
  * multiple instances are accessed, should I find a more efficient way to access them?
- * @todo: check if eventActionFunctionStatus should be private or not
- * @todo: check if eventAction map of definitions should be private or not
+ * @todo check if eventActionFunctionStatus should be private or not
+ * @todo check if eventAction map of definitions should be private or not
  */
 class EventActionService : public Service {
 private:
diff --git a/inc/Services/EventReportService.hpp b/inc/Services/EventReportService.hpp
index dc24b92c15fe50ae6688cba87dc88259bc022e1e..839dff8bc3ca013acee789fbb9ad257b730fa18e 100644
--- a/inc/Services/EventReportService.hpp
+++ b/inc/Services/EventReportService.hpp
@@ -8,8 +8,8 @@
  * Implementation of ST[05] event reporting service
  *
  * @ingroup Services
- * @todo: add more enums event IDs
- * @todo: Make sure there isn't an event ID == 0, because there's a confliction with another service
+ * @todo add more enums event IDs
+ * @todo Make sure there isn't an event ID == 0, because there's a confliction with another service
  * Note: enum IDs are these just for test purposes
  *
  */
diff --git a/inc/Services/FunctionManagementService.hpp b/inc/Services/FunctionManagementService.hpp
index 6f2bc55b34a202f86124690ce2a55059701aaf29..4dd0922560dc4d550045ade585dc3b5d4e2dd942 100644
--- a/inc/Services/FunctionManagementService.hpp
+++ b/inc/Services/FunctionManagementService.hpp
@@ -7,6 +7,9 @@
 #include "Service.hpp"
 #include "ErrorHandler.hpp"
 
+typedef String<ECSSFunctionNameLength> functionName;
+typedef etl::map<functionName, void (*)(String<ECSSFunctionMaxArgLength>), ECSSFunctionMapSize> FunctionMap;
+
 /**
  * Implementation of the ST[08] function management service
  *
@@ -24,34 +27,6 @@
  * @ingroup Services
  * @author Grigoris Pavlakis <grigpavl@ece.auth.gr>
  */
-
-/**
- * Usage of the include() function:
- *
- * @code
- * void foo(String<MAX_ARG_LENGTH> b) {
- * 		std::cout << "SPAAAACE!" << std::endl;
- * 	}
- *
- * void bar(String<MAX_ARG_LENGTH> b) {
- * 		std::cout << "I HAZ A CUBESAT THAT SNAPS PIX!" << std::endl;
- * 	}
- *
- * void baz(String<MAX_ARG_LENGTH> b) {
- * 		std::cout << "QWERTYUIOP" << std::endl;
- * 	}
- *
- * 	FunctionManagementService::FunctionManagementService() {
- * 		include(String<FUNC_NAME_LENGTH>("foo"), &foo);
- * 		include(String<FUNC_NAME_LENGTH>("bar"), &bar);
- * 		include(String<FUNC_NAME_LENGTH>("baz"), &baz);
- * 	}
- * @endcode
- */
-
-typedef String<ECSSFunctionNameLength> functionName;
-typedef etl::map<functionName, void (*)(String<ECSSFunctionMaxArgLength>), ECSSFunctionMapSize> FunctionMap;
-
 class FunctionManagementService : public Service {
 	/**
 	 * Map of the function names to their respective pointers. Size controlled by FUNC_MAP_SIZE
@@ -84,6 +59,28 @@ public:
 	 * Includes a new function in the pointer map. This enables it to be called by way of a valid
 	 * TC[8,1] message.
 	 *
+	 * Usage of the include() function:
+	 *
+	 * @code
+	 * void foo(String<MAX_ARG_LENGTH> b) {
+	 * 		std::cout << "SPAAAACE!" << std::endl;
+	 * 	}
+	 *
+	 * void bar(String<MAX_ARG_LENGTH> b) {
+	 * 		std::cout << "I HAZ A CUBESAT THAT SNAPS PIX!" << std::endl;
+	 * 	}
+	 *
+	 * void baz(String<MAX_ARG_LENGTH> b) {
+	 * 		std::cout << "QWERTYUIOP" << std::endl;
+	 * 	}
+	 *
+	 * 	FunctionManagementService::FunctionManagementService() {
+	 * 		include(String<FUNC_NAME_LENGTH>("foo"), &foo);
+	 * 		include(String<FUNC_NAME_LENGTH>("bar"), &bar);
+	 * 		include(String<FUNC_NAME_LENGTH>("baz"), &baz);
+	 * 	}
+	 * @endcode
+	 *
 	 * @param funcName the function's name. Max. length is FUNC_NAME_LENGTH bytes.
 	 * @param ptr pointer to a function of void return type and a MAX_ARG_LENGTH-lengthed byte
 	 * string as argument (which contains the actual arguments of the function)
diff --git a/inc/Services/HousekeepingService.hpp b/inc/Services/HousekeepingService.hpp
index 4ee886911f9a2b72a917f92c9d5e0cb82eb7c2fa..2b6ac2331e711fd0b144b162ed548c5a51de8df0 100644
--- a/inc/Services/HousekeepingService.hpp
+++ b/inc/Services/HousekeepingService.hpp
@@ -11,6 +11,7 @@
  * Implementation of the ST[03] Housekeeping Reporting Service. The job of the Housekeeping Service is to store
  * parameters in the housekeeping structures so that it can generate housekeeping reports periodically.
  *
+ * @ingroup Services
  * @author Petridis Konstantinos <petridkon@gmail.com>
  */
 class HousekeepingService : Service {
diff --git a/inc/Services/ParameterService.hpp b/inc/Services/ParameterService.hpp
index c932f3c6239a25344317aac0e257a028cb3ad252..437bd395ad06cffe0a97ef1d2959d4f2c531ee2f 100644
--- a/inc/Services/ParameterService.hpp
+++ b/inc/Services/ParameterService.hpp
@@ -12,16 +12,15 @@
  * Implementation of the ST[20] parameter management service,
  * as defined in ECSS-E-ST-70-41C
  *
- * @author Grigoris Pavlakis <grigpavl@ece.auth.gr>
- * @author Athanasios Theocharis <athatheoc@gmail.com>
- */
-
-/**
  * Parameter manager - ST[20]
  *
  * The purpose of this class is to handle functions regarding the access and modification
  * of the various parameters of the CubeSat.
  * The parameters to be managed are initialized and kept in \ref SystemParameters.
+ *
+ * @ingroup Services
+ * @author Grigoris Pavlakis <grigpavl@ece.auth.gr>
+ * @author Athanasios Theocharis <athatheoc@gmail.com>
  */
 class ParameterService : public Service {
 private:
diff --git a/inc/Services/ParameterStatisticsService.hpp b/inc/Services/ParameterStatisticsService.hpp
index d4bcd8a65e8f1e119de34859c30a76bfd8c56aa8..b6f98580fca55357a6968d90fb7c4e9342e05db4 100644
--- a/inc/Services/ParameterStatisticsService.hpp
+++ b/inc/Services/ParameterStatisticsService.hpp
@@ -10,6 +10,8 @@
 
 /**
  * Implementation of the ST[04] parameter statistics reporting service, as defined in ECSS-E-ST-70-41C.
+ *
+ * @ingroup Services
  * @author Konstantinos Petridis <petridkon@gmail.com>
  */
 class ParameterStatisticsService : public Service {