From 98989c618181c29aaa44433232091f936d83cd87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Wed, 6 Apr 2022 14:19:09 +0200
Subject: [PATCH 01/37] Add exit screen

---
 barrier/optic_barrier_sw/main.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index 9666658..0af1601 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -141,7 +141,7 @@ struct state {
     int64_t best_time_us;
 } state;
 
-enum screen { EMPTY, TIME, SHUTDOWN };
+enum screen { EMPTY, TIME, SHUTDOWN, EXIT };
 
 void update_display(enum screen screen)
 {
@@ -179,6 +179,11 @@ void update_display(enum screen screen)
 
         break;
     }
+    case EXIT: {
+        GUI_DisString_EN(0, 0, "Hold 5s to exit", &Font12, FONT_BACKGROUND, WHITE);
+
+        break;
+    }
     }
     GUI_Display();
 }

From 8f4763cd2574c2a4c01b17c9d9f597a6d3112079 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Wed, 6 Apr 2022 14:19:34 +0200
Subject: [PATCH 02/37] Rename shutdown timeval to avoid conflicts

---
 barrier/optic_barrier_sw/main.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index 0af1601..ae4fae9 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -195,20 +195,20 @@ int64_t usec_between(const struct timeval *start, const struct timeval *stop)
 
 void shutdown_handler(bool btn_pressed)
 {
-    static struct timeval start;
+    static struct timeval start1;
     struct timeval now;
 
     if (!btn_pressed) {
-        start = (struct timeval){0, 0};
+        start1 = (struct timeval){0, 0};
         return;
     }
 
-    if (start.tv_sec == 0)
-        gettimeofday(&start, NULL);
+    if (start1.tv_sec == 0)
+        gettimeofday(&start1, NULL);
 
     gettimeofday(&now, NULL);
 
-    if (usec_between(&start, &now) > 5*1000000) {
+    if (usec_between(&start1, &now) > 5*1000000) {
         update_display(EMPTY);
         System_Exit();
         system("sudo shutdown -h now");

From 5a43f901c19f4f513ca09525ce7ff112f642fed9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Wed, 6 Apr 2022 14:19:40 +0200
Subject: [PATCH 03/37] Add exit handler

---
 barrier/optic_barrier_sw/main.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index ae4fae9..06b254a 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -216,6 +216,28 @@ void shutdown_handler(bool btn_pressed)
     }
 }
 
+void exit_handler(bool btn_pressed)
+{
+    static struct timeval start2;
+    struct timeval now;
+
+    if (!btn_pressed) {
+        start2 = (struct timeval){0, 0};
+        return;
+    }
+
+    if (start2.tv_sec == 0)
+        gettimeofday(&start2, NULL);
+
+    gettimeofday(&now, NULL);
+
+    if (usec_between(&start2, &now) > 5*1000000) {
+        update_display(EMPTY);
+        System_Exit();
+        exit(0);
+    }
+}
+
 int main(int argc, char *argv[])
 {
     // 1.System Initialization

From 50059309d162050e9f34ab345091dfb3dc4c022a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Wed, 6 Apr 2022 14:19:56 +0200
Subject: [PATCH 04/37] Run exit handler on pressing second button

---
 barrier/optic_barrier_sw/main.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index 06b254a..8905e0c 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -280,9 +280,13 @@ int main(int argc, char *argv[])
         if (digitalRead(SHUTDOWN_BUTTON) == 1) {
             update_display(SHUTDOWN);
             shutdown_handler(true);
+        } else if (digitalRead(UNIVERSAL_BUTTON2) == 1) {
+            update_display(EXIT);
+            exit_handler(true);
         } else {
             update_display(TIME);
             shutdown_handler(false);
+            exit_handler(false);
         }
 
         if (after_start) {

From 2b1d8402aceffaea471393cdee04506455a50f1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Thu, 7 Apr 2022 10:41:17 +0200
Subject: [PATCH 05/37] Add git configure file for cmake

---
 barrier/optic_barrier_sw/git.h.in | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 barrier/optic_barrier_sw/git.h.in

diff --git a/barrier/optic_barrier_sw/git.h.in b/barrier/optic_barrier_sw/git.h.in
new file mode 100644
index 0000000..0355944
--- /dev/null
+++ b/barrier/optic_barrier_sw/git.h.in
@@ -0,0 +1,7 @@
+#define GIT_AVAILABLE @GIT_AVAILABLE@
+
+#define GIT_DESCRIBE "@GIT_DESCRIBE@"
+
+#define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@"
+
+#define GIT_IS_DIRTY @GIT_IS_DIRTY@

From aed04630fb7333386233e94b1618d96875c545f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Thu, 7 Apr 2022 10:42:02 +0200
Subject: [PATCH 06/37] Add git sequence to CMakeLists

Inspired by:
https://stackoverflow.com/questions/1435953/how-can-i-pass-git-sha1-to-compiler-as-definition-using-cmake
https://github.com/andrew-hardin/cmake-git-version-tracking
---
 barrier/optic_barrier_sw/CMakeLists.txt | 52 +++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/barrier/optic_barrier_sw/CMakeLists.txt b/barrier/optic_barrier_sw/CMakeLists.txt
index a9bbe30..43498d0 100644
--- a/barrier/optic_barrier_sw/CMakeLists.txt
+++ b/barrier/optic_barrier_sw/CMakeLists.txt
@@ -2,6 +2,58 @@ cmake_minimum_required(VERSION 3.1.0)
 
 project(optic_barrier_sw)
 
+# Git versioning
+set(PRE_CONFIGURE_FILE "git.h.in")
+set(POST_CONFIGURE_FILE "git.h")
+
+# Check whether we have git
+execute_process(
+    COMMAND git --version
+    RESULT_VARIABLE GIT_CHECK
+)
+
+if("${GIT_CHECK}" EQUAL 0)
+    set(GIT_AVAILABLE true)
+else()
+    set(GIT_AVAILABLE false)
+endif()
+
+# Preset variables
+set(GIT_IS_DIRTY false)
+
+if(GIT_AVAILABLE)
+    # Git describe
+    execute_process(
+        COMMAND git describe --always --tags
+        OUTPUT_VARIABLE GIT_DESCRIBE
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+
+    # Commit hash
+    execute_process(
+        COMMAND git log -1 --format=%h
+        OUTPUT_VARIABLE GIT_COMMIT_HASH
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+
+    # Dirty
+    execute_process(
+        COMMAND git status --porcelain -uno
+        RESULT_VARIABLE GIT_DIRTY
+    )
+
+    if ("${GIT_DIRTY}" STREQUAL "")
+        set(GIT_IS_DIRTY false)
+    else()
+        set(GIT_IS_DIRTY true)
+    endif()
+endif()
+
+get_filename_component(PRE_CONFIGURE_FILE "${PRE_CONFIGURE_FILE}" ABSOLUTE)
+get_filename_component(POST_CONFIGURE_FILE "${POST_CONFIGURE_FILE}" ABSOLUTE)
+
+configure_file("${PRE_CONFIGURE_FILE}" "${POST_CONFIGURE_FILE}" @ONLY)
+
 # If you want to use different compiler than arm-linux-gnueabihf-gcc, run cmake as:
 # cmake -DHARDCODE_C_COMPILER=NO -DCMAKE_C_COMPILER=...
 set(HARDCODE_C_COMPILER YES CACHE BOOL "Override user's (or default) value of CMAKE_C_COMPILER with 'arm-linux-gnueabihf-gcc'")

From 0b360932b355bdb16b4b3de06e2be157aff36809 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Thu, 7 Apr 2022 10:42:39 +0200
Subject: [PATCH 07/37] Display git version on exit screen

---
 barrier/optic_barrier_sw/main.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index 8905e0c..e7839e1 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -40,6 +40,8 @@
 #include "OLED_GUI.h"
 #include "Show_Lib.h"
 
+#include "git.h"
+
 #define BARRIER_SIGNAL 0     // 30
 #define UNIVERSAL_BUTTON1 19 // 24
 #define UNIVERSAL_BUTTON2 26 // 25
@@ -182,6 +184,19 @@ void update_display(enum screen screen)
     case EXIT: {
         GUI_DisString_EN(0, 0, "Hold 5s to exit", &Font12, FONT_BACKGROUND, WHITE);
 
+        char version[100];
+
+        if (GIT_AVAILABLE) {
+            if (GIT_IS_DIRTY) {
+                sprintf(version, "%s-dirty", GIT_DESCRIBE);
+            } else {
+                sprintf(version, "%s", GIT_DESCRIBE);
+            }
+        } else {
+            sprintf(version, "Unknown version");
+        }
+
+        GUI_DisString_EN(0, 3 * Font8.Height, version, &Font8, FONT_BACKGROUND, WHITE);
         break;
     }
     }

From 55da123dd0c700e234e410e2ff1a22276ad1f8c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Fri, 8 Apr 2022 09:21:07 +0200
Subject: [PATCH 08/37] Kill explicitly websocat on exit

---
 barrier/optic_barrier_sw/main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index e7839e1..efa824a 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -249,6 +249,7 @@ void exit_handler(bool btn_pressed)
     if (usec_between(&start2, &now) > 5*1000000) {
         update_display(EMPTY);
         System_Exit();
+        system("pkill websocat"); // FIXME: This is currently only way how I can force quit on websocat.
         exit(0);
     }
 }

From 91113b4585be0adaa80c81331e240d06a94d6bcb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Fri, 8 Apr 2022 09:26:52 +0200
Subject: [PATCH 09/37] (.GI) Add git.h

---
 barrier/optic_barrier_sw/.gitignore | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 barrier/optic_barrier_sw/.gitignore

diff --git a/barrier/optic_barrier_sw/.gitignore b/barrier/optic_barrier_sw/.gitignore
new file mode 100644
index 0000000..e0c8fd1
--- /dev/null
+++ b/barrier/optic_barrier_sw/.gitignore
@@ -0,0 +1 @@
+git.h

From e625be42c2c308711ada117d40ccd343e52494bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Fri, 8 Apr 2022 10:30:52 +0200
Subject: [PATCH 10/37] (F) Marking version dirty

---
 barrier/optic_barrier_sw/CMakeLists.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/barrier/optic_barrier_sw/CMakeLists.txt b/barrier/optic_barrier_sw/CMakeLists.txt
index 43498d0..fbb436a 100644
--- a/barrier/optic_barrier_sw/CMakeLists.txt
+++ b/barrier/optic_barrier_sw/CMakeLists.txt
@@ -39,7 +39,8 @@ if(GIT_AVAILABLE)
     # Dirty
     execute_process(
         COMMAND git status --porcelain -uno
-        RESULT_VARIABLE GIT_DIRTY
+        OUTPUT_VARIABLE GIT_DIRTY
+        OUTPUT_STRIP_TRAILING_WHITESPACE
     )
 
     if ("${GIT_DIRTY}" STREQUAL "")

From 418d7dfc7f9fec2da2e0f0e5b8b0d33b40b079a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Fri, 8 Apr 2022 10:56:36 +0200
Subject: [PATCH 11/37] Reverse the functions order when pressing buttons

---
 barrier/optic_barrier_sw/main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index efa824a..1315c02 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -294,11 +294,11 @@ int main(int argc, char *argv[])
         }
 
         if (digitalRead(SHUTDOWN_BUTTON) == 1) {
-            update_display(SHUTDOWN);
             shutdown_handler(true);
+            update_display(SHUTDOWN);
         } else if (digitalRead(UNIVERSAL_BUTTON2) == 1) {
-            update_display(EXIT);
             exit_handler(true);
+            update_display(EXIT);
         } else {
             update_display(TIME);
             shutdown_handler(false);

From 1133b06840bcf416886dc9708f19d36e8a1c2971 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Fri, 8 Apr 2022 10:57:00 +0200
Subject: [PATCH 12/37] Make start structs global

---
 barrier/optic_barrier_sw/main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index 1315c02..07584dc 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -145,6 +145,9 @@ struct state {
 
 enum screen { EMPTY, TIME, SHUTDOWN, EXIT };
 
+static struct timeval start1;
+static struct timeval start2;
+
 void update_display(enum screen screen)
 {
     GUI_Clear();
@@ -210,7 +213,6 @@ int64_t usec_between(const struct timeval *start, const struct timeval *stop)
 
 void shutdown_handler(bool btn_pressed)
 {
-    static struct timeval start1;
     struct timeval now;
 
     if (!btn_pressed) {
@@ -233,7 +235,6 @@ void shutdown_handler(bool btn_pressed)
 
 void exit_handler(bool btn_pressed)
 {
-    static struct timeval start2;
     struct timeval now;
 
     if (!btn_pressed) {

From ec7b18e985bbe27629f36a021baa0f88bd413132 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Fri, 8 Apr 2022 10:57:17 +0200
Subject: [PATCH 13/37] Move usec_between slightly more to the top

---
 barrier/optic_barrier_sw/main.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index 07584dc..3a07efc 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -148,6 +148,11 @@ enum screen { EMPTY, TIME, SHUTDOWN, EXIT };
 static struct timeval start1;
 static struct timeval start2;
 
+int64_t usec_between(const struct timeval *start, const struct timeval *stop)
+{
+    return (stop->tv_sec - start->tv_sec) * 1000000LL + stop->tv_usec - start->tv_usec;
+}
+
 void update_display(enum screen screen)
 {
     GUI_Clear();
@@ -206,11 +211,6 @@ void update_display(enum screen screen)
     GUI_Display();
 }
 
-int64_t usec_between(const struct timeval *start, const struct timeval *stop)
-{
-    return (stop->tv_sec - start->tv_sec) * 1000000LL + stop->tv_usec - start->tv_usec;
-}
-
 void shutdown_handler(bool btn_pressed)
 {
     struct timeval now;

From 399ac9d141bd5d2799c91c419102e9c25c496cd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Fri, 8 Apr 2022 10:57:28 +0200
Subject: [PATCH 14/37] Display progress on exit/shutdown

---
 barrier/optic_barrier_sw/main.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index 3a07efc..3cfcf4c 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -174,7 +174,14 @@ void update_display(enum screen screen)
         break;
     }
     case SHUTDOWN: {
+        struct timeval now;
+        gettimeofday(&now, NULL);
+
         GUI_DisString_EN(0, 0, "Hold 5s to pwroff", &Font12, FONT_BACKGROUND, WHITE);
+        //GUI_DisString_EN(usec_between(&start1, &now) / 41322, (Font12.Height / 2) - 1, "-", &Font12, FONT_BACKGROUND, WHITE);
+        GUI_DisString_EN(usec_between(&start1, &now) / 41322, 2*Font12.Height - 4, "_", &Font12, FONT_BACKGROUND, WHITE);
+
+
         char host[NI_MAXHOST];
         get_ip_address(host);
         char str[100];
@@ -190,7 +197,14 @@ void update_display(enum screen screen)
         break;
     }
     case EXIT: {
+        struct timeval now;
+        gettimeofday(&now, NULL);
+
         GUI_DisString_EN(0, 0, "Hold 5s to exit", &Font12, FONT_BACKGROUND, WHITE);
+        // MAX_TIME / (DISPLAY_WIDTH - FONT_WIDTH)
+        // 5000000 / (128 - 7)
+        //GUI_DisString_EN(usec_between(&start2, &now) / 41322, Font12.Height - 2, "-", &Font12, FONT_BACKGROUND, WHITE);
+        GUI_DisString_EN(usec_between(&start2, &now) / 41322, 0, "_", &Font12, FONT_BACKGROUND, WHITE);
 
         char version[100];
 

From 0393658f055b4833f3173f044a4240ecd78c6235 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 12 Apr 2022 13:00:41 +0200
Subject: [PATCH 15/37] Add Arrowhead Tools logo

---
 doc/Arrowhead_tools_blue.png | Bin 0 -> 24277 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 doc/Arrowhead_tools_blue.png

diff --git a/doc/Arrowhead_tools_blue.png b/doc/Arrowhead_tools_blue.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d1c3202c4107473de3ce5e59115764cf88883f3
GIT binary patch
literal 24277
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

literal 0
HcmV?d00001


From 599a7724869b72c757ac5987e222494746d7df24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 12 Apr 2022 13:17:31 +0200
Subject: [PATCH 16/37] Add backend overlay

---
 backend-arrowhead/.gitignore  |  4 +++
 backend-arrowhead/README.md   | 47 +++++++++++++++++++++++++
 backend-arrowhead/overlay.py3 | 66 +++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)
 create mode 100644 backend-arrowhead/.gitignore
 create mode 100644 backend-arrowhead/README.md
 create mode 100644 backend-arrowhead/overlay.py3

diff --git a/backend-arrowhead/.gitignore b/backend-arrowhead/.gitignore
new file mode 100644
index 0000000..2c76cc4
--- /dev/null
+++ b/backend-arrowhead/.gitignore
@@ -0,0 +1,4 @@
+*.p12
+*.pub
+*.ca
+ahconf.py
diff --git a/backend-arrowhead/README.md b/backend-arrowhead/README.md
new file mode 100644
index 0000000..5cc38ea
--- /dev/null
+++ b/backend-arrowhead/README.md
@@ -0,0 +1,47 @@
+# f1tenth-scoreapp-backend-arrowhead
+_An Arrowhead compliant overlay for backend._
+
+
+## Requirements
+- `aclpy >= 0.2.0`
+  - GitHub: [https://github.com/CTU-IIG/ah-acl-py](https://github.com/CTU-IIG/ah-acl-py)
+  - Wheel: [v0.2.0](https://github.com/jara001/ah-acl-py/releases/download/v0.2.0/aclpy-0.2.0-py3-none-any.whl)
+
+
+## Usage
+
+1. Obtain certificates (`.p12`, `.pub`) for your system from your local Arrowhead Core.
+2. Obtain also the certificate authority `.ca` for your cloud.
+3. Create a configuration file `ahconf.py`.
+4. Run the `overlay.py3`.
+
+
+## Configuration example
+
+```python
+Server = ArrowheadServer(
+    address = "192.168.1.22",
+)
+
+Interface = ArrowheadInterface(
+    name = "HTTP-INSECURE-JSON",
+)
+
+Service = ArrowheadService(
+    name = "scoreapp",
+    metadata = {
+        "authorization": "secret",
+    },
+)
+
+Client = ArrowheadClient(
+    name = "overlay",
+    address = "192.168.12.22",
+    port = 4110,
+    p12file = "overlay.p12",
+    p12pass = "SomeSecurePassword",
+    cafile = "authority.ca",
+    server = Server,
+    interfaces = [Interface],
+)
+```
diff --git a/backend-arrowhead/overlay.py3 b/backend-arrowhead/overlay.py3
new file mode 100644
index 0000000..a59cadd
--- /dev/null
+++ b/backend-arrowhead/overlay.py3
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+# overlay.py3
+"""Arrowhead Compliant overlay."""
+
+######################
+# Arrowhead Configuration
+######################
+
+from aclpy.client.client_pkcs12 import ArrowheadClient
+from aclpy.interface import ArrowheadInterface
+from aclpy.server import ArrowheadServer
+from aclpy.service import ArrowheadService
+
+exec(open("ahconf.py", "rb").read())
+"""Expected contents:
+Server = ArrowheadServer(
+    address = AH_CORE_IP_ADDRESS,
+)
+
+Interface = ArrowheadInterface(
+    name = NAME_OF_THE_INTERFACE,
+)
+
+Service = ArrowheadService(
+    name = NAME_OF_THE_SERVICE,
+)
+
+Client = ArrowheadClient(
+    name = NAME_OF_THE_SYSTEM,
+    address = SYSTEM_IP_ADDRESS,
+    port = SYSTEM_PORT,
+    pubfile = PATH_TO_PUB_FILE,
+    p12file = PATH_TO_P12_FILE,
+    p12pass = PASS_TO_P12_FILE,
+    cafile = PATH_TO_CA_FILE,
+    server = Server,
+    interfaces = [Interface],
+)
+"""
+
+import signal
+
+def exit_sequence(sig, frame):
+    Client.unregister_service(Service)
+
+
+signal.signal(signal.SIGTERM, exit_sequence)
+
+######################
+# Arrowhead Sequence
+######################
+
+import time, os
+
+if not Client.register_service(Service):
+    Client.unregister_service(Service)
+
+    if not Client.register_service(Service):
+        print (Client.last_error)
+        exit (1)
+
+print ("Registered to AHCore with:\n\tInterface ID: %d\n\tProvider ID: %d\n\tService ID: %d" % (Interface.id, Client.id, Service.id))
+
+os.system("../backend/scoreapp")
+
+exit_sequence(signal.SIGTERM, None)

From b26e2500d855578e0c8193289ad300c48fa649ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 12 Apr 2022 13:19:30 +0200
Subject: [PATCH 17/37] (.GI) Add scoreapp database

---
 backend-arrowhead/.gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/backend-arrowhead/.gitignore b/backend-arrowhead/.gitignore
index 2c76cc4..ca085b3 100644
--- a/backend-arrowhead/.gitignore
+++ b/backend-arrowhead/.gitignore
@@ -2,3 +2,4 @@
 *.pub
 *.ca
 ahconf.py
+scoreapp.db

From 091e655f90ea11e034176bf352ccc02e4ef85afc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 12 Apr 2022 13:25:56 +0200
Subject: [PATCH 18/37] Get and display current branch

---
 barrier/optic_barrier_sw/CMakeLists.txt | 7 +++++++
 barrier/optic_barrier_sw/git.h.in       | 2 ++
 barrier/optic_barrier_sw/main.c         | 1 +
 3 files changed, 10 insertions(+)

diff --git a/barrier/optic_barrier_sw/CMakeLists.txt b/barrier/optic_barrier_sw/CMakeLists.txt
index fbb436a..9cba94b 100644
--- a/barrier/optic_barrier_sw/CMakeLists.txt
+++ b/barrier/optic_barrier_sw/CMakeLists.txt
@@ -48,6 +48,13 @@ if(GIT_AVAILABLE)
     else()
         set(GIT_IS_DIRTY true)
     endif()
+
+    # Branch name
+    execute_process(
+        COMMAND git rev-parse --abbrev-ref HEAD
+        OUTPUT_VARIABLE GIT_BRANCH_NAME
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
 endif()
 
 get_filename_component(PRE_CONFIGURE_FILE "${PRE_CONFIGURE_FILE}" ABSOLUTE)
diff --git a/barrier/optic_barrier_sw/git.h.in b/barrier/optic_barrier_sw/git.h.in
index 0355944..7d56853 100644
--- a/barrier/optic_barrier_sw/git.h.in
+++ b/barrier/optic_barrier_sw/git.h.in
@@ -5,3 +5,5 @@
 #define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@"
 
 #define GIT_IS_DIRTY @GIT_IS_DIRTY@
+
+#define GIT_BRANCH_NAME "@GIT_BRANCH_NAME@"
diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index 3cfcf4c..f011d04 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -218,6 +218,7 @@ void update_display(enum screen screen)
             sprintf(version, "Unknown version");
         }
 
+        GUI_DisString_EN(0, 2 * Font8.Height, GIT_BRANCH_NAME, &Font8, FONT_BACKGROUND, WHITE);
         GUI_DisString_EN(0, 3 * Font8.Height, version, &Font8, FONT_BACKGROUND, WHITE);
         break;
     }

From 548543b436b5ecaa5b9d2bc97fd8a718f2e5b8f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 12 Apr 2022 13:30:16 +0200
Subject: [PATCH 19/37] Exit the application during exit sequence

---
 backend-arrowhead/overlay.py3 | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/backend-arrowhead/overlay.py3 b/backend-arrowhead/overlay.py3
index a59cadd..a85d183 100644
--- a/backend-arrowhead/overlay.py3
+++ b/backend-arrowhead/overlay.py3
@@ -43,6 +43,8 @@ import signal
 def exit_sequence(sig, frame):
     Client.unregister_service(Service)
 
+    exit(0)
+
 
 signal.signal(signal.SIGTERM, exit_sequence)
 

From efdad507fd3d42bc890e46fe3ad784265cfda5c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Wed, 13 Apr 2022 12:32:58 +0200
Subject: [PATCH 20/37] Update metadata example of backend overlay to latest
 version

---
 backend-arrowhead/README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/backend-arrowhead/README.md b/backend-arrowhead/README.md
index 5cc38ea..7c2ac9c 100644
--- a/backend-arrowhead/README.md
+++ b/backend-arrowhead/README.md
@@ -31,6 +31,8 @@ Service = ArrowheadService(
     name = "scoreapp",
     metadata = {
         "authorization": "secret",
+        "endpoint_1": "barrier/1",
+        "endpoint_2": "barrier/2",
     },
 )
 

From 4dfd275d0d63b8727f57b4d9c8467a36b74ce168 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Wed, 13 Apr 2022 13:35:16 +0200
Subject: [PATCH 21/37] Add raspberry overlay as submodule

---
 .gitmodules       | 3 +++
 barrier-arrowhead | 1 +
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 barrier-arrowhead

diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..0a47a39
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "barrier-arrowhead"]
+	path = barrier-arrowhead
+	url = https://github.com/jara001/ah-raspi-overlay
diff --git a/barrier-arrowhead b/barrier-arrowhead
new file mode 160000
index 0000000..e674a78
--- /dev/null
+++ b/barrier-arrowhead
@@ -0,0 +1 @@
+Subproject commit e674a783959de37d388a607c91a4c7025b925470

From 4a24b982f24991af41f2554b5e34e0ca40c01e1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 19 Apr 2022 12:46:16 +0200
Subject: [PATCH 22/37] Update the raspberry overlay submodule

---
 barrier-arrowhead | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/barrier-arrowhead b/barrier-arrowhead
index e674a78..f97761e 160000
--- a/barrier-arrowhead
+++ b/barrier-arrowhead
@@ -1 +1 @@
-Subproject commit e674a783959de37d388a607c91a4c7025b925470
+Subproject commit f97761e91c8074a58c6adf6750763f02cbc3b60e

From 6dec8272ab64b5c7d184f7423f2e7f3987437fdc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 19 Apr 2022 13:36:06 +0200
Subject: [PATCH 23/37] Roll poweroff screen and show wireguard address

---
 barrier/optic_barrier_sw/main.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index f011d04..68334c5 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -66,7 +66,7 @@ void interrupt_optic_barrier()
     pthread_mutex_unlock(&detect_mutex);
 }
 
-int get_ip_address(char *host)
+int get_ip_address(char *host, char *wghost)
 {
     struct ifaddrs *ifa;
     int family, s; // n;
@@ -86,7 +86,11 @@ int get_ip_address(char *host)
         family = ifa->ifa_addr->sa_family;
 
         if (family == AF_INET) {
-            s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+            if (strcmp("wg0", ifa->ifa_name) == 0) {
+                s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), wghost, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+            } else {
+                s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+            }
             if (s != 0) {
                 printf("getnameinfo() failed: %s\n", gai_strerror(s));
                 return EXIT_FAILURE;
@@ -153,6 +157,8 @@ int64_t usec_between(const struct timeval *start, const struct timeval *stop)
     return (stop->tv_sec - start->tv_sec) * 1000000LL + stop->tv_usec - start->tv_usec;
 }
 
+bool roll = false;
+
 void update_display(enum screen screen)
 {
     GUI_Clear();
@@ -183,9 +189,14 @@ void update_display(enum screen screen)
 
 
         char host[NI_MAXHOST];
-        get_ip_address(host);
+        char wg_host[NI_MAXHOST];
+        get_ip_address(host, wg_host);
         char str[100];
-        sprintf(str, "IP: %s", host);
+        if (roll) {
+            sprintf(str, "WG: %s", wg_host);
+        } else {
+            sprintf(str, "IP: %s", host);
+        }
         GUI_DisString_EN(0, Font12.Height - 2, str, &Font12, FONT_BACKGROUND, WHITE);
 
         char name_user[32];
@@ -223,6 +234,9 @@ void update_display(enum screen screen)
         break;
     }
     }
+
+    roll = !roll;
+
     GUI_Display();
 }
 

From 96933c20a608dd6d52c6cce0c003b688816564d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 19 Apr 2022 13:39:17 +0200
Subject: [PATCH 24/37] Slow down the rolling

---
 barrier/optic_barrier_sw/main.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index 68334c5..aa2adfd 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -157,6 +157,8 @@ int64_t usec_between(const struct timeval *start, const struct timeval *stop)
     return (stop->tv_sec - start->tv_sec) * 1000000LL + stop->tv_usec - start->tv_usec;
 }
 
+int roll_time = 5;
+int roll_current_time = 0;
 bool roll = false;
 
 void update_display(enum screen screen)
@@ -235,7 +237,12 @@ void update_display(enum screen screen)
     }
     }
 
-    roll = !roll;
+    roll_current_time++;
+
+    if (roll_current_time >= roll_time) {
+        roll = !roll;
+        roll_current_time = 0;
+    }
 
     GUI_Display();
 }

From 0c342616e1bd6d42a04488b2dd91c97229cda7c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 19 Apr 2022 13:39:53 +0200
Subject: [PATCH 25/37] (F) Set default value of wireguard address

---
 barrier/optic_barrier_sw/main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index aa2adfd..cbce549 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -192,6 +192,7 @@ void update_display(enum screen screen)
 
         char host[NI_MAXHOST];
         char wg_host[NI_MAXHOST];
+        sprintf(wg_host, "");
         get_ip_address(host, wg_host);
         char str[100];
         if (roll) {

From fa5ca9490ce9e8c8422260df21332bad2d9ccf49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 19 Apr 2022 13:40:07 +0200
Subject: [PATCH 26/37] Hide wireguard address when not obtained

---
 barrier/optic_barrier_sw/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/barrier/optic_barrier_sw/main.c b/barrier/optic_barrier_sw/main.c
index cbce549..bcefa4a 100644
--- a/barrier/optic_barrier_sw/main.c
+++ b/barrier/optic_barrier_sw/main.c
@@ -195,7 +195,7 @@ void update_display(enum screen screen)
         sprintf(wg_host, "");
         get_ip_address(host, wg_host);
         char str[100];
-        if (roll) {
+        if (roll && strcmp(wg_host, "") != 0) {
             sprintf(str, "WG: %s", wg_host);
         } else {
             sprintf(str, "IP: %s", host);

From b519356104deb757fc9b8358ddfd7809bf9772c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Wed, 20 Apr 2022 12:21:55 +0200
Subject: [PATCH 27/37] Set raspberry overlay submodule to track branch

---
 .gitmodules | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitmodules b/.gitmodules
index 0a47a39..061638a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,4 @@
 [submodule "barrier-arrowhead"]
 	path = barrier-arrowhead
 	url = https://github.com/jara001/ah-raspi-overlay
+	branch = master

From 7494469f6cc543c6818499d228fc98c6126b4e16 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Wed, 20 Apr 2022 12:25:55 +0200
Subject: [PATCH 28/37] Update the raspberry overlay submodule

---
 barrier-arrowhead | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/barrier-arrowhead b/barrier-arrowhead
index f97761e..4f77c43 160000
--- a/barrier-arrowhead
+++ b/barrier-arrowhead
@@ -1 +1 @@
-Subproject commit f97761e91c8074a58c6adf6750763f02cbc3b60e
+Subproject commit 4f77c4310a60eae707c335e53c1f9e6a952a293c

From d9fb602b0224bb4e598a46ebd9a8fff566f86740 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <jaroslavklapalek@seznam.cz>
Date: Wed, 20 Apr 2022 13:32:38 +0200
Subject: [PATCH 29/37] Update backend-arrowhead readme

---
 backend-arrowhead/README.md | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/backend-arrowhead/README.md b/backend-arrowhead/README.md
index 7c2ac9c..00ab1b8 100644
--- a/backend-arrowhead/README.md
+++ b/backend-arrowhead/README.md
@@ -1,6 +1,14 @@
 # f1tenth-scoreapp-backend-arrowhead
 _An Arrowhead compliant overlay for backend._
 
+This application serves as an Arrowhead overlay for the **F1Tenth Scoreapp** (backend). It registers itself as an Arrowhead Service `scoreapp` and launches the backend scoreapp itself. Provided Service is consumed by the optical barriers.
+
+The Service `scoreapp` provided by this overlay has following metadata:
+- `authorization` -- secret keyphrase for authorizing the barrier (it is used by the barrier to authorize itself with the scoreapp)
+- `endpoint_X` -- available endpoint for the barrier to connect to
+
+_Note: The amount of endpoints is not limited. Each parameter starting with `endpoint_` should be treated as an endpoint option._
+
 
 ## Requirements
 - `aclpy >= 0.2.0`

From b93ff12e39a3fb330555b2e41b751c9766defb6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <jaroslavklapalek@seznam.cz>
Date: Fri, 22 Apr 2022 13:53:45 +0200
Subject: [PATCH 30/37] Add new draft of the readme

---
 README.md | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index dab7926..56a4be3 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,26 @@
-# f1tenth-scoreapp
+# F1Tenth Scoreapp
+
+**F1Tenth Scoreapp** is a complete solution for measuring lap time on a racing track, which was developed for [International F1/10 Autonomous Racing Competition](https://f1tenth.org/).
 
 This project consists of several parts:
 1. [frontend](./frontend/) (client-side React.js app)
 2. [backend](./backend/) (Go server providing REST and WebSocket APIs)
-3. [optical barrier code and design](./barrier/) (KiCAD, C, Czech)
+3. [backend-arrowhead](./backend-arrowhead/) (Arrowhead Compliant overlay for launching the backend)
+4. [optical barrier code and design](./barrier/) (KiCAD, C, Czech)
+5. [barrier-arrowhead](./barrier-arrowhead/) (Arrowhead Compliant overlay for the optic barrier)
 
 ![Optical barrier based on Raspberry Pi Zero](doc/barrier.jpg)
+
+
+## License
+
+F1tenth Scoreapp is released under the **TODO LICENSE**.
+
+
+## About Arrowhead Tools
+
+<img src="https://www.eclipse.org/org/research/images/research/arrowheadtools.png" alt="Arrowhead Tools logo" width="150" />
+
+This project has been developed by [Industrial Informatics Department](https://iid.ciirc.cvut.cz/) that is a part of [Czech Institute of Informatics, Robotics and Cybernetics](https://ciirc.cvut.cz/), Czech Technical University in Prague. It has received funding from the EU ECSEL Joint Undertaking and the Ministry of Education of the Czech Republic under grant agreement n° 826452 and 8A19011 (project Arrowhead Tools).
+
+The [Arrowhead Tools](https://arrowhead.eu/arrowheadtools) project aims for digitalisation and automation solutions for the European industry, which will close the gaps that hinder the IT/OT integration by introducing new technologies in an open source platform for the design and run-time engineering of IoT and System of Systems. The project will provide engineering processes, integration platform, tools and tool chains for the cost-efficient development of digitalisation, connectivity and automation system solutions in various fields of application.

From 38df38513d2f088a13887779c530862419247c25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Tue, 3 May 2022 08:57:57 +0200
Subject: [PATCH 31/37] Add logo to backend overlay and add status messages

---
 backend-arrowhead/arrowhead_logo.bmp | Bin 0 -> 2426 bytes
 backend-arrowhead/overlay.py3        |  31 ++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 backend-arrowhead/arrowhead_logo.bmp

diff --git a/backend-arrowhead/arrowhead_logo.bmp b/backend-arrowhead/arrowhead_logo.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..38e3ff44cbfddf66c6b943c29e72173077720399
GIT binary patch
literal 2426
zcmb7_1yoc^9EU$jNogC!MoI+>TST!iP!uH;sfDFMR1^zE1w_SeY*7>w17X+h?(Xhx
zeRp?Ro=@t$-#K%4cIG?ZoSA#?|2n$FX(3OXI)n&43!#|{O$ANiDntW}brek)luh91
z>>4ef`yUt8B3Km_6;xGKQBzYxU0odw4GqeaDMQ(^Wzp2sL`zExZEbCIbac?w)kRNF
zk8<V8p|7uxfq?;rhK3j!8DVT}jERW}rlzKpFJGPt6)I4%Vnr%dszl|=m8nvt3RSCC
z#mvl%YSpSyy?S-b&CRJ%qXso=)}&UgTGXyxn>uysP`7Sf>eZ`<g@pz6>(|H9(h@5x
zE3B=pv9Yni*4CB=4I0p}VM7`<YJ{Dg9rpJ2G;Z9OCQX{qv}seCHETxm=FM?%aG*tt
z7PM^Hl2)x+(YkeO+O%my+qP|K*RCDy+qcKj(UA@vI^g8wM8}RD>C~wc&d$zs?%bI!
zUAoY<Ygf8;>qhtP-Enbop+}D%^z7M_UcGwJyLWF~U0vzZrw@Jm_QlQ3jeh<5(Z7Fx
z+}+(7Fkk=!2M)x;!vjxGPrSUm@b>m*(4avK9y}NyA0LJc8G^5`FMfW0`1|`45D-9M
zU?3uqh@hY#f`fw*i^YV5gb*4UN?2GJ;o;##L_`o78A()B6w%Sq#Kgofbm&lGV`CXM
zY#76b4`;-P5yZvCF>>TcMvWRpe0)5kM~`OAm@$kUJC<?d#xZ{UcoGs4m@r`i6DLk2
zF)@)zlO{2F@?@q=nL<)h63NNQq@<)Ub?Q`7Q&X8XZ5q?3PiMxA8KkA9F>~fjX3d(#
z?Af!KGiMHS=gwu`ym`!@Kc58)7O-&PLKZDr#Nx$^S+ZmaOP4MsJw2Ue%a*Zx`EpjQ
zSi#DbD_ON_6{}aTX3d&4tX;d7jEoG{ty{<X_3O#Z%w)rc4Q$-Fk*usNHf`F(=FOYg
zvSkZfw{B(Iwry<RzMbssY<BF}!OopK*|lpIyLay<CntwJd-jl<n@e6^9ukQJsZ`3|
zy?fcWZy)>j@8`gQ0~|bfkVA(Karp3IjvP6{(W6H>cI+6(k00m6i4&YWd6HA7PI3D5
zY0jKE!`ZWEId|?H=g*(#!i5W5ym*mImo9Pn@@1}Exx&?}SGjiW8rQF1=f;g2+`M^{
zTeog;`}S?_+_}TuyLY*F?;iK>-{--D2RwZEkVlUm@%Zs$o;-QN)2B~)_UswYpFiit
zix<3n`I1+!Uh(?%Yu>zh!`ruSdH3!e@87@Y!-o%i{P>YipFZ*V^Jl(%`NG$)U-|a!
z8{fZw=f{s9{QUWoU%!6w`}gmHYM|%uR8(mwn9uL%iX|Sh>hpJ0gqk6XP`zZ)5lf|>
zMQ~>Bal!*9#7}_*ON!*|Qia<hORm4%Cc~s&g?#pDa!9~@WkpguNQOzH)P#EWM>HIi
zSe{6RX^G^RG&{yico_@g6Q7xH%k%pa%O5QKlP8juY^^|rt?<0k<}a`80i|G)V8sW(
zS9nPaB_T(tmjr6dP6S!4Rz}~%Fu!Y`k<UrQ!l&Y|*d(SW+sVglmB%X)6~<J&1&5#P
ztgTa&wh-OFT*6-!kuVz}a5e>4a1mGmXPKODlZF<BDLJbGOsrRUQRTX^)=5fRc)21m
zg)b{ziHVEB6r7ThM(7u9%iph(3oRD=k1w)#>`yM#ptwbq`<1U7RTB2EFU+t6+rRsW
nE*Vq$!i`F_DSa`eVG3WQaVa*1FSc|{=8HBh)ds3=C1U>o^Fy(q

literal 0
HcmV?d00001

diff --git a/backend-arrowhead/overlay.py3 b/backend-arrowhead/overlay.py3
index a85d183..6538d3a 100644
--- a/backend-arrowhead/overlay.py3
+++ b/backend-arrowhead/overlay.py3
@@ -1,6 +1,29 @@
 #!/usr/bin/env python3
 # overlay.py3
 """Arrowhead Compliant overlay."""
+######################
+# Logo
+######################
+
+from PIL import Image
+# https://stackoverflow.com/questions/68957686/pillow-how-to-binarize-an-image-with-threshold
+arrowhead_logo = Image.open("arrowhead_logo.bmp") \
+                      .convert("L") \
+                      .point( lambda p: 255 if p > 20 else 0 ) \
+                      .convert("1") \
+                      .resize((16, 9))
+
+import sys
+
+def show_arrowhead_logo():
+    for y in range(arrowhead_logo.height):
+        for x in range(arrowhead_logo.width):
+            if arrowhead_logo.getpixel((x, y)):
+                sys.stdout.write("#")
+            else:
+                sys.stdout.write(" ")
+        print("")
+
 
 ######################
 # Arrowhead Configuration
@@ -54,6 +77,10 @@ signal.signal(signal.SIGTERM, exit_sequence)
 
 import time, os
 
+show_arrowhead_logo()
+print ("Arrowhead backend overlay starting up...\n")
+
+print ("Registering '%s' service to Arrowhead Core..." % Service.name)
 if not Client.register_service(Service):
     Client.unregister_service(Service)
 
@@ -61,8 +88,10 @@ if not Client.register_service(Service):
         print (Client.last_error)
         exit (1)
 
-print ("Registered to AHCore with:\n\tInterface ID: %d\n\tProvider ID: %d\n\tService ID: %d" % (Interface.id, Client.id, Service.id))
+print ("> Registration successful.")
+print ("> Interface ID: %d\n> Provider ID: %d\n> Service ID: %d\n" % (Interface.id, Client.id, Service.id))
 
+print ("Starting scoreapp...")
 os.system("../backend/scoreapp")
 
 exit_sequence(signal.SIGTERM, None)

From 2695f3a0810d7181b1a5e730626bb6cf101d9869 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Thu, 12 May 2022 15:06:07 +0200
Subject: [PATCH 32/37] Add license file

---
 LICENSE   | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 README.md |   2 +-
 2 files changed, 675 insertions(+), 1 deletion(-)
 create mode 100644 LICENSE

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/README.md b/README.md
index 56a4be3..116340d 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ This project consists of several parts:
 
 ## License
 
-F1tenth Scoreapp is released under the **TODO LICENSE**.
+F1tenth Scoreapp is released under the **GPLv3** license.
 
 
 ## About Arrowhead Tools

From d3382158764af596c0294fc2ef671953cfdd5d81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Mon, 23 May 2022 08:12:28 +0200
Subject: [PATCH 33/37] Move arrowhead overlays to 'arrowhead' folder

---
 .gitmodules                                         |   2 +-
 {backend-arrowhead => arrowhead/backend}/.gitignore |   0
 {backend-arrowhead => arrowhead/backend}/README.md  |   0
 .../backend}/arrowhead_logo.bmp                     | Bin
 .../backend}/overlay.py3                            |   0
 barrier-arrowhead => arrowhead/barrier              |   0
 6 files changed, 1 insertion(+), 1 deletion(-)
 rename {backend-arrowhead => arrowhead/backend}/.gitignore (100%)
 rename {backend-arrowhead => arrowhead/backend}/README.md (100%)
 rename {backend-arrowhead => arrowhead/backend}/arrowhead_logo.bmp (100%)
 rename {backend-arrowhead => arrowhead/backend}/overlay.py3 (100%)
 rename barrier-arrowhead => arrowhead/barrier (100%)

diff --git a/.gitmodules b/.gitmodules
index 061638a..c438a20 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,4 @@
 [submodule "barrier-arrowhead"]
-	path = barrier-arrowhead
+	path = arrowhead/barrier
 	url = https://github.com/jara001/ah-raspi-overlay
 	branch = master
diff --git a/backend-arrowhead/.gitignore b/arrowhead/backend/.gitignore
similarity index 100%
rename from backend-arrowhead/.gitignore
rename to arrowhead/backend/.gitignore
diff --git a/backend-arrowhead/README.md b/arrowhead/backend/README.md
similarity index 100%
rename from backend-arrowhead/README.md
rename to arrowhead/backend/README.md
diff --git a/backend-arrowhead/arrowhead_logo.bmp b/arrowhead/backend/arrowhead_logo.bmp
similarity index 100%
rename from backend-arrowhead/arrowhead_logo.bmp
rename to arrowhead/backend/arrowhead_logo.bmp
diff --git a/backend-arrowhead/overlay.py3 b/arrowhead/backend/overlay.py3
similarity index 100%
rename from backend-arrowhead/overlay.py3
rename to arrowhead/backend/overlay.py3
diff --git a/barrier-arrowhead b/arrowhead/barrier
similarity index 100%
rename from barrier-arrowhead
rename to arrowhead/barrier

From 29492ea404b76ade09547ea4af4d770f0f8f55dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Mon, 23 May 2022 08:14:30 +0200
Subject: [PATCH 34/37] Update links in the readme and use term wrapper

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 116340d..4d8a530 100644
--- a/README.md
+++ b/README.md
@@ -5,9 +5,9 @@
 This project consists of several parts:
 1. [frontend](./frontend/) (client-side React.js app)
 2. [backend](./backend/) (Go server providing REST and WebSocket APIs)
-3. [backend-arrowhead](./backend-arrowhead/) (Arrowhead Compliant overlay for launching the backend)
+3. [Arrowhead backend wrapper](./arrowhead/backend/) (Arrowhead Compliant wrapper for launching the backend)
 4. [optical barrier code and design](./barrier/) (KiCAD, C, Czech)
-5. [barrier-arrowhead](./barrier-arrowhead/) (Arrowhead Compliant overlay for the optic barrier)
+5. [Arrowhead barrier wrapper](./barrier-arrowhead/) (Arrowhead Compliant wrapper for the optic barrier)
 
 ![Optical barrier based on Raspberry Pi Zero](doc/barrier.jpg)
 

From 4cb998bc6492c754156ed6228d4d27b4700e905c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Mon, 23 May 2022 08:16:22 +0200
Subject: [PATCH 35/37] (F) Path to the scoreapp in Arrowhead wrapper

---
 arrowhead/backend/overlay.py3 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arrowhead/backend/overlay.py3 b/arrowhead/backend/overlay.py3
index 6538d3a..107a712 100644
--- a/arrowhead/backend/overlay.py3
+++ b/arrowhead/backend/overlay.py3
@@ -92,6 +92,6 @@ print ("> Registration successful.")
 print ("> Interface ID: %d\n> Provider ID: %d\n> Service ID: %d\n" % (Interface.id, Client.id, Service.id))
 
 print ("Starting scoreapp...")
-os.system("../backend/scoreapp")
+os.system("../../backend/scoreapp")
 
 exit_sequence(signal.SIGTERM, None)

From 39b5ab7c5ddc8bfb062b71faa589ff731335fa2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Mon, 23 May 2022 08:23:23 +0200
Subject: [PATCH 36/37] Change the license to TODO until resolved

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 4d8a530..4918a71 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ This project consists of several parts:
 
 ## License
 
-F1tenth Scoreapp is released under the **GPLv3** license.
+F1tenth Scoreapp is released under the **TODO** license. Reach us for more information.
 
 
 ## About Arrowhead Tools

From ee001da45f3cc9df35d2fb643982a7e9a85ea8c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20Klap=C3=A1lek?= <klapajar@fel.cvut.cz>
Date: Mon, 23 May 2022 08:24:38 +0200
Subject: [PATCH 37/37] Rename the license file

---
 LICENSE => LICENSE.tobeused | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename LICENSE => LICENSE.tobeused (100%)

diff --git a/LICENSE b/LICENSE.tobeused
similarity index 100%
rename from LICENSE
rename to LICENSE.tobeused