diff --git a/config_comred.cmake b/config_comred.cmake index f06480e..75835e5 100644 --- a/config_comred.cmake +++ b/config_comred.cmake @@ -118,6 +118,7 @@ set(BOBBYCAR_BUILDFLAGS -DOLD_NVS -DFEATURE_DNS_NS -DSWITCH_BLINK + -DFEATURE_ESPNOW ) if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ignore/lockscreen_plugin.cmake") diff --git a/icons/greenpass.png b/icons/greenpass.png new file mode 100644 index 0000000..fbd57d3 Binary files /dev/null and b/icons/greenpass.png differ diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 54f5599..ff686f3 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -81,6 +81,7 @@ set(headers displays/menus/gametrakmodesettingsmenu.h displays/menus/genericwifisettingsmenu.h displays/menus/graphsmenu.h + displays/menus/greenpassmenu.h displays/menus/handbremssettingsmenu.h displays/menus/invertmenu.h displays/menus/larsmmodesettingsmenu.h @@ -130,6 +131,8 @@ set(headers dpad6wire.h drivingstatistics.h esptexthelpers.h + espnowfunctions.h + espnowwrapper.h feedbackparser.h globals.h handbremse.h @@ -142,6 +145,7 @@ set(headers icons/close.h icons/demos.h icons/graph.h + icons/greenpass.h icons/hardware.h icons/info.h icons/lock.h @@ -281,6 +285,7 @@ set(sources displays/menus/gametrakmodesettingsmenu.cpp displays/menus/genericwifisettingsmenu.cpp displays/menus/graphsmenu.cpp + displays/menus/greenpassmenu.cpp displays/menus/handbremssettingsmenu.cpp displays/menus/invertmenu.cpp displays/menus/larsmmodesettingsmenu.cpp @@ -330,6 +335,8 @@ set(sources dpad6wire.cpp drivingstatistics.cpp esptexthelpers.cpp + espnowfunctions.cpp + espnowwrapper.cpp feedbackparser.cpp globals.cpp handbremse.cpp @@ -342,6 +349,7 @@ set(sources icons/close.cpp icons/demos.cpp icons/graph.cpp + icons/greenpass.cpp icons/hardware.cpp icons/info.cpp icons/lock.cpp diff --git a/main/displays/menus/greenpassmenu.cpp b/main/displays/menus/greenpassmenu.cpp new file mode 100644 index 0000000..df66874 --- /dev/null +++ b/main/displays/menus/greenpassmenu.cpp @@ -0,0 +1,49 @@ +#include "greenpassmenu.h" + +#include + +// local includes +#include "actions/switchscreenaction.h" +#include "displays/menus/mainmenu.h" +#include "icons/back.h" + +using namespace espgui; + +namespace greenpassmenu { +bool showingQRCode{false}; +} // namespace + +void GreenPassMenu::ShowCertAction::triggered() { + greenpassmenu::showingQRCode = true; + m_qrcode.init(); + m_qrcode.createScaleToFit(""); +} + +GreenPassMenu::GreenPassMenu() +{ + constructMenuItem, ShowCertAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void GreenPassMenu::initScreen() +{ + Base::initScreen(); + greenpassmenu::showingQRCode = false; +} + +void GreenPassMenu::rotate(int offset) +{ + if (greenpassmenu::showingQRCode) + GreenPassMenu::initScreen(); + Base::rotate(offset); +} + +void GreenPassMenu::back() +{ + if (greenpassmenu::showingQRCode) + { + GreenPassMenu::initScreen(); + } + else + switchScreen(); +} diff --git a/main/displays/menus/greenpassmenu.h b/main/displays/menus/greenpassmenu.h new file mode 100644 index 0000000..a024dc3 --- /dev/null +++ b/main/displays/menus/greenpassmenu.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +// local includes +#include "menudisplay.h" +#include "texts.h" + +namespace greenpassmenu { +extern bool showingQRCode; +} // namespace + +class GreenPassMenu : + public espgui::MenuDisplay, + public espgui::StaticText +{ + using Base = espgui::MenuDisplay; +public: + GreenPassMenu(); + void back() override; + void rotate(int offset) override; + void initScreen() override; + + class ShowCertAction : public virtual espgui::ActionInterface { + public: + void triggered() override; + private: + qrcode::QRcode m_qrcode{}; + }; +}; diff --git a/main/displays/menus/mainmenu.cpp b/main/displays/menus/mainmenu.cpp index 9625b8c..6a675b4 100644 --- a/main/displays/menus/mainmenu.cpp +++ b/main/displays/menus/mainmenu.cpp @@ -19,6 +19,7 @@ #include "displays/menus/settingsmenu.h" #include "displays/menus/mosfetsmenu.h" #include "displays/menus/demosmenu.h" +#include "displays/menus/greenpassmenu.h" #include "displays/lockscreen.h" #include "displays/garagedisplay.h" #include "displays/menus/otamenu.h" @@ -45,6 +46,7 @@ #include "icons/poweroff.h" #include "icons/reboot.h" #include "icons/statistics.h" +#include "icons/greenpass.h" using namespace espgui; @@ -72,6 +74,7 @@ MainMenu::MainMenu() if (SHOWITEM) { constructMenuItem, SwitchScreenAction>>(); } #endif constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::demos>>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::greenpass>>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::lock>>>(); #ifdef FEATURE_GARAGE if (SHOWITEM) { constructMenuItem, SwitchScreenAction>>(); } diff --git a/main/espnowfunctions.cpp b/main/espnowfunctions.cpp new file mode 100644 index 0000000..befadfb --- /dev/null +++ b/main/espnowfunctions.cpp @@ -0,0 +1,41 @@ +constexpr const char * const TAG = "BOBBY_ESP_NOW"; +#ifdef FEATURE_ESPNOW +#include "espnowfunctions.h" + +#include +#include +#include + +namespace espnow { + +void onReceive(const uint8_t *mac_addr, const uint8_t *data, int data_len) +{ + const std::string data_str(data, data+data_len); + + size_t sep_pos = data_str.find(":"); + if (std::string::npos != sep_pos) + { + std::string msg_type = data_str.substr(0, sep_pos); + std::string msg = data_str.substr(sep_pos, data_str.length()-1); + ESP_LOGI(TAG, "Type: %s - Message: %s", msg_type.c_str(), msg.c_str()); + } + else + { + ESP_LOGW(TAG, "Invalid message: Could not find ':'"); + } +} + +void initESPNow() +{ + ESP_LOGI(TAG, "Initializing esp now..."); + ESPNow.reg_recv_cb(onReceive); + ESPNow.init(); +} + +void onRecvTs(uint64_t millis) +{ + +} + +} // namespace espnow +#endif diff --git a/main/espnowfunctions.h b/main/espnowfunctions.h new file mode 100644 index 0000000..f3b25be --- /dev/null +++ b/main/espnowfunctions.h @@ -0,0 +1,11 @@ +#pragma once +#ifdef FEATURE_ESPNOW +#include + +namespace espnow { +constexpr const uint8_t broadcast_address[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +void onReceive(const uint8_t *mac_addr, const uint8_t *data, int data_len); +void initESPNow(); +void onRecvTs(uint64_t millis); +} // namespace espnow +#endif diff --git a/main/espnowwrapper.cpp b/main/espnowwrapper.cpp new file mode 100644 index 0000000..a6c5ef3 --- /dev/null +++ b/main/espnowwrapper.cpp @@ -0,0 +1,42 @@ +#include "espnowwrapper.h" + +#include +#include + +namespace espnow { +class ESPNowW32 : public IESPNowW { + public: + virtual esp_err_t add_peer(uint8_t *mac, int channel); + virtual esp_err_t remove_peer(uint8_t *mac); + virtual esp_err_t send_message(uint8_t *mac, uint8_t *data, size_t datalen); + + private: + std::list peers; +}; + +esp_err_t ESPNowW32::add_peer(uint8_t *mac, int channel) { + peers.push_back(esp_now_peer_info_t{}); + esp_now_peer_info_t &peer = peers.back(); + std::memcpy(peer.peer_addr, mac, sizeof(peer.peer_addr)); + peer.channel = channel; + peer.ifidx = WIFI_IF_STA; + auto success = esp_now_add_peer(&peers.back()); + if (success != ESP_OK) + remove_peer(mac); + return success; +} +esp_err_t ESPNowW32::remove_peer(uint8_t *mac) { + // find peer in peers + for (auto it = peers.begin(); it != peers.end();) { + if (0 == memcmp(mac, it->peer_addr, sizeof(it->peer_addr))) { + it = peers.erase(it); // remove it + } + } + return esp_now_del_peer(mac); +} +esp_err_t ESPNowW32::send_message(uint8_t *mac, uint8_t *data, size_t datalen) { + return esp_now_send(mac, data, datalen); +} +ESPNowW32 espnow = ESPNowW32(); +IESPNowW &ESPNow = espnow; +} diff --git a/main/espnowwrapper.h b/main/espnowwrapper.h new file mode 100644 index 0000000..b3d6620 --- /dev/null +++ b/main/espnowwrapper.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +namespace espnow { +class IESPNowW { + public: + virtual int add_peer(uint8_t *mac, int channel = 0) = 0; + virtual int remove_peer(uint8_t *mac) = 0; + virtual int send_message(uint8_t *mac, uint8_t *data, size_t datalen) = 0; + virtual int init() { return esp_now_init(); } + int reg_send_cb(esp_now_send_cb_t cb) { + return esp_now_register_send_cb(cb); + } + int reg_recv_cb(esp_now_recv_cb_t cb) { + return esp_now_register_recv_cb(cb); + } + int unreg_send_cb() { return esp_now_unregister_send_cb(); } + int unreg_recv_cb() { return esp_now_unregister_recv_cb(); } +}; + +extern IESPNowW &ESPNow; +} // namespace diff --git a/main/icons/greenpass.cpp b/main/icons/greenpass.cpp new file mode 100644 index 0000000..0a24589 --- /dev/null +++ b/main/icons/greenpass.cpp @@ -0,0 +1,42 @@ +#include "greenpass.h" + +namespace bobbyicons { +const espgui::Icon<24, 24> greenpass{{ + 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0010 (16) pixels + 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0020 (32) pixels + 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650D, 0x4CAA, // 0x0030 (48) pixels + 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x0040 (64) pixels + 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650D, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0050 (80) pixels + 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, // 0x0060 (96) pixels + 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x0070 (112) pixels + 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0080 (128) pixels + 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, // 0x0090 (144) pixels + 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x00A0 (160) pixels + 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x00B0 (176) pixels + 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, // 0x00C0 (192) pixels + 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x00D0 (208) pixels + 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650D, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x00E0 (224) pixels + 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x00F0 (240) pixels + 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0100 (256) pixels + 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0110 (272) pixels + 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0120 (288) pixels + 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0130 (304) pixels + 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0140 (320) pixels + 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0xB676, 0xF7BE, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0150 (336) pixels + 0x4CAA, 0x4CAA, 0x54CB, 0x54CB, 0x54CB, 0x54CB, 0x54CB, 0x54CB, 0x54CB, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x0160 (352) pixels + 0xF7BE, 0xF7BE, 0x4CAA, 0x54CB, 0x54CB, 0x54CB, 0x4CAA, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0170 (368) pixels + 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0x650C, 0x4CAA, // 0x0180 (384) pixels + 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x0190 (400) pixels + 0xF7BE, 0xF7BE, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0x650C, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x01A0 (416) pixels + 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0x8590, 0x4CAA, // 0x01B0 (432) pixels + 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x01C0 (448) pixels + 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x01D0 (464) pixels + 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x6D2E, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x8590, // 0x01E0 (480) pixels + 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, // 0x01F0 (496) pixels + 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0200 (512) pixels + 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0210 (528) pixels + 0x4CAA, 0x54CB, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x54CB, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x54CB, 0x7D6F, // 0x0220 (544) pixels + 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0xF79D, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0230 (560) pixels + 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0240 (576) pixels +}, "greenpass"}; +} // namespace bobbyicons diff --git a/main/icons/greenpass.h b/main/icons/greenpass.h new file mode 100644 index 0000000..437b069 --- /dev/null +++ b/main/icons/greenpass.h @@ -0,0 +1,7 @@ +#pragma once + +#include "icon.h" + +namespace bobbyicons { +extern const espgui::Icon<24, 24> greenpass; +} // namespace bobbyicons diff --git a/main/main.cpp b/main/main.cpp index 8682c81..c2fce5e 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -81,7 +81,9 @@ using namespace std::chrono_literals; #endif #include "drivingstatistics.h" #include "newsettings.h" - +#ifdef FEATURE_ESPNOW +#include "espnowfunctions.h" +#endif namespace { std::optional lastWifiUpdate; std::optional lastPotiRead; @@ -291,6 +293,9 @@ extern "C" void app_main() else espgui::switchScreen(); #endif +#ifdef FEATURE_ESPNOW + espnow::initESPNow(); +#endif while (true) { diff --git a/main/texts.cpp b/main/texts.cpp index 6a99d0c..1111207 100644 --- a/main/texts.cpp +++ b/main/texts.cpp @@ -539,4 +539,9 @@ char TEXT_SELECT_BRANCH[] = "Select Branch"; char TEXT_SELECT_BRANCH_CLEAR[] = "Clear Branch"; char TEXT_QRCODE_DEBUG[] = "QR Debug"; + +//GreenPassMenu +char TEXT_GREENPASS[] = "Green Pass"; +char TEXT_SHOWCERT[] = "Show cert"; + } // namespace diff --git a/main/texts.h b/main/texts.h index 37f8c10..ebbe24f 100644 --- a/main/texts.h +++ b/main/texts.h @@ -539,6 +539,10 @@ extern char TEXT_SELECT_BRANCH_CLEAR[]; //QrCodeDebug extern char TEXT_QRCODE_DEBUG[]; + +//GreenPassMenu +extern char TEXT_GREENPASS[]; +extern char TEXT_SHOWCERT[]; } // namespace using namespace bobbytexts;