cash2ecash

cash2ecash: cash acceptor that issues digital cash (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit 42c3a0d6a1a283bf84845336876b14b3190376b7
parent 2e8d55a7b6e1491bb2c0e6697aefc0f2e3e3afd5
Author: Manuel Geissbühler <manuel@debian>
Date:   Mon, 30 Dec 2024 12:39:28 +0100

draft of gui finished, draft of state machine finished

Diffstat:
Msrc/cash2ecash.cpp | 226+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Dsrc/gui/#screenWelcomme.hpp# | 38--------------------------------------
Msrc/gui/screenAcceptCash.hpp | 12++++++++++--
Msrc/gui/screenConnection.hpp | 12++++++++++--
Msrc/gui/screenIdentification.hpp | 10+++++++---
Msrc/gui/screenWelcomme.hpp | 14+++++++++++---
Asrc/include/global.hpp | 24++++++++++++++++++++++++
Msrc/include/gui.hpp | 3+++
8 files changed, 247 insertions(+), 92 deletions(-)

diff --git a/src/cash2ecash.cpp b/src/cash2ecash.cpp @@ -3,28 +3,194 @@ #include <iostream> #include <ostream> #include <src/misc/lv_types.h> - - - +#include <vector> #include "cashacceptors.hpp" +#include "gui/screen.hpp" +#include "gui/screenAcceptCash.hpp" +#include "gui/screenConnection.hpp" +#include "gui/screenIdentification.hpp" +#include "gui/screenWelcomme.hpp" #include "utils.hpp" #include "gui.hpp" +#include "global.hpp" -//callback function for button start -void startButtonCb(lv_event_t *e){ - std::cout << "button start was clicked" << std::endl; -} // Global Definitions -enum state_e { INIT, SLEEP, IDLE, CONNECTION, ACCEPTCASH, DONE }; +enum state_e { + INIT, + SLEEP, + IDLE, + CONNECTION, + ACCEPTCASH, + DONE, + IDENTIFICATION, + ENUM_STATE_END +}; +#define NUMBER_OF_STATES 7 + enum state_e state = INIT; char test; -char *string; +char hello[] = "hello"; +char world[] = "wold"; +char *string = hello; Gui gui; -ScreenWelcome welcome(&startButtonCb); +Screen screenWelcome = ScreenWelcome(); +Screen screenIdentification = ScreenIdentification(); +Screen screenConnection = ScreenConnection(); +Screen screenAcceptCash = ScreenAcceptCash(string); void guiDriver(); +typedef void(*action_t)(); + +typedef struct { + action_t action; + state_e nextState; +} stateEventPair; + +stateEventPair stateEventTable[NUMBER_OF_STATES][NUMBER_OF_EVENTS]; +//std::vector< std::vector<stateEventPair> >stateEvent2dVector(6, std::vector<stateEventPair>(4)); + + +void actionEventInitialize() { + std::cout << "Event action initialze called" << std::endl; + gui.setActiveScreen(&screenWelcome); +} + +void actionEventUnexpected(){ + std::cerr << "Event not expected in this state" << std::endl; +} + +void actionEventStart(){ + std::cout << "Action Event Start called" << std::endl; + gui.setActiveScreen(&screenIdentification); +} + +void actionEventAbortIdent(){ + std::cout << "Action Event Abort Ident called" << std::endl; + gui.setActiveScreen(&screenWelcome); +} + +void actionEventAbortConnection(){ + std::cout << "Action Abort Connection called" << std::endl; + gui.setActiveScreen(&screenWelcome); +} + +void actionEventFinishCashin(){ + std::cout << "Action Event Finish Cashin called" << std::endl; + gui.setActiveScreen(&screenWelcome); +} + +void actionEventSleep() { std::cout << "Action Event xx called" << std::endl; } + +void actionEventWakeup() { std::cout << "Action Event xx called" << std::endl; } + +void actionEventIdentificationSuccess(){ + std::cout << "Action Event xx called" << std::endl; + gui.setActiveScreen(&screenConnection); +} + +void actionEventBankTokenDone(){ + std::cout << "Action Event Bank Token called" << std::endl; +} + +void actionEventBankWithdrawalDone(){ + std::cout << "Action Event Bank Withdrawal called" << std::endl; +} + +void actionEventBankWStatusConfirmed(){ + std::cout << "Action Event Bank Withdrawal Status Confirmed called" << std::endl; + gui.setActiveScreen(&screenAcceptCash); +} + +void actionEventBankWStatusPending(){ + std::cout << "Action Event Bank Withdrawal Status Pending called" << std::endl; +} + +void actionEventWConfirmationDone(){ + std::cout << "Action Event Bank Confirmation Done called" << std::endl; + gui.setActiveScreen(&screenWelcome); +} + +void actionEventIdentificationTimeout(){ + std::cout << "Action Event Identification Timeout called" << std::endl; + gui.setActiveScreen(&screenWelcome); +} + +void actionEventAcceptCashTimeout(){ + std::cout << "Action Event Acceptcash Timeout called" << std::endl; + gui.setActiveScreen(&screenWelcome); +} + +void actionEventConnectionTimeout(){ + std::cout << "Action Event Connection Timeout called" << std::endl; + gui.setActiveScreen(&screenWelcome); +} + +void actionEventDoneTimeout() { + std::cout << "Action Event Done Timeout called" << std::endl; + gui.setActiveScreen(&screenWelcome); +} + + + + +void initStateEvent(){ + //Runtime initialzation is used due to convienient array indexing. + //Initzialize all state-event pairs to handleuUnexpectedEvent + int state, event; + for (state = 0; state < ENUM_STATE_END; state++) { + for (event = 0; event < ENUM_EVENT_END; event++) { + stateEventTable[state][event].action = &actionEventUnexpected; + stateEventTable[state][event].nextState = (state_e)state; + } + } + + //Overwrite desired state-event pairs to provide actual functionality + stateEventTable[INIT][EVENT_INITIALIZE].action = actionEventInitialize; + stateEventTable[INIT][EVENT_INITIALIZE].nextState = IDLE; + stateEventTable[IDLE][EVENT_BUTTON_START].action = actionEventStart; + stateEventTable[IDLE][EVENT_BUTTON_START].nextState = IDENTIFICATION; + stateEventTable[IDLE][EVENT_SLEEP].action = actionEventSleep; + stateEventTable[IDLE][EVENT_SLEEP].nextState = SLEEP; + + stateEventTable[SLEEP][EVENT_WAKEUP].action = actionEventWakeup; + stateEventTable[SLEEP][EVENT_WAKEUP].nextState = IDLE; + + stateEventTable[IDENTIFICATION][EVENT_BUTTON_ABORT].action = actionEventAbortIdent; + stateEventTable[IDENTIFICATION][EVENT_BUTTON_ABORT].nextState = IDLE; + stateEventTable[IDENTIFICATION][EVENT_IDENTIFICATION_SUCCESS].action = actionEventIdentificationSuccess; + stateEventTable[IDENTIFICATION][EVENT_IDENTIFICATION_SUCCESS].nextState = CONNECTION; + stateEventTable[IDENTIFICATION][EVENT_TIMEOUT].action = actionEventIdentificationTimeout; + stateEventTable[IDENTIFICATION][EVENT_TIMEOUT].nextState = IDLE; + + stateEventTable[CONNECTION][EVENT_BUTTON_ABORT].action = actionEventAbortConnection; + stateEventTable[CONNECTION][EVENT_BUTTON_ABORT].nextState = IDLE; + stateEventTable[CONNECTION][EVENT_BANK_TOKEN_DONE].action = actionEventBankTokenDone; + stateEventTable[CONNECTION][EVENT_BANK_TOKEN_DONE].nextState = CONNECTION; + stateEventTable[CONNECTION][EVENT_BANK_WITHDRAWAL_DONE].action = actionEventBankWithdrawalDone; + stateEventTable[CONNECTION][EVENT_BANK_WITHDRAWAL_DONE].nextState = CONNECTION; + stateEventTable[CONNECTION][EVENT_BANK_W_STATUS_PENDING].action = actionEventBankWStatusPending; + stateEventTable[CONNECTION][EVENT_BANK_W_STATUS_PENDING].nextState = CONNECTION; + stateEventTable[CONNECTION][EVENT_BANK_W_STATUS_CONFIRMED].action = actionEventBankWStatusConfirmed; + stateEventTable[CONNECTION][EVENT_BANK_W_STATUS_CONFIRMED].nextState = ACCEPTCASH; + stateEventTable[CONNECTION][EVENT_TIMEOUT].action = actionEventConnectionTimeout; + stateEventTable[CONNECTION][EVENT_TIMEOUT].nextState = IDLE; + + stateEventTable[ACCEPTCASH][EVENT_BUTTON_FINISH_CASHIN].action = actionEventFinishCashin; + stateEventTable[ACCEPTCASH][EVENT_BUTTON_FINISH_CASHIN].nextState = DONE; + stateEventTable[ACCEPTCASH][EVENT_TIMEOUT].action = actionEventAcceptCashTimeout; + stateEventTable[ACCEPTCASH][EVENT_TIMEOUT].nextState = DONE; + stateEventTable[DONE][EVENT_TIMEOUT].action = actionEventDoneTimeout; + stateEventTable[DONE][EVENT_TIMEOUT].nextState = IDLE; +} + + +void eventHandler(event_e event){ + stateEventTable[state][event].action(); + state = stateEventTable[state][event].nextState; +} + int main(int argc, char *argv[]){ char serialpath[] = "/dev/ttyAMA3"; std::cout << "The Program is running" <<std::endl; @@ -34,41 +200,13 @@ int main(int argc, char *argv[]){ TALER_Amount testamount; + //Initialize State Machine + initStateEvent(); + + //Trigger Initialzation Event + eventHandler(EVENT_INITIALIZE); + while (true) { - switch (state) { - case INIT: - gui.setActiveScreen(dynamic_cast<Screen*>(&welcome)); - state = ACCEPTCASH; - timer1.start(); - //cashacceptor.startMoneyAcceptance(); - break; - case SLEEP: - break; - case IDLE: - break; - case CONNECTION: - break; - case ACCEPTCASH: - if (timer1.over()) { - //cashacceptor.stopMoneyAcceptance(); - //cashacceptor.readAccumulated(&testamount); - string = TALER_amount_to_string(&testamount); - printf("%s\n",string); - free(string); - //cashacceptor.readFIFO(&testamount); - string = TALER_amount_to_string(&testamount); - printf("b%s\n", string); - free(string); - state = DONE; - } - - break; - case DONE: - break; - default: - std::cout << "ERROR: unhandeled state" << std::endl; - break; - } guiDriver(); } } diff --git a/src/gui/#screenWelcomme.hpp# b/src/gui/#screenWelcomme.hpp# @@ -1,38 +0,0 @@ -#ifndef SCREEN_WELCOME_H -#define SCREEN_WELCOME_H -#include "screen.hpp" -#include <cstdint> -#include <src/core/lv_obj_event.h> -#include <src/core/lv_obj_pos.h> -#include <src/core/lv_obj_style.h> -#include <src/misc/lv_area.h> -#include <src/misc/lv_event.h> -#include <src/misc/lv_types.h> -#include <src/widgets/button/lv_button.h> -#include <src/widgets/label/lv_label.h> - -class ScreenWelcome : public Screen { -private: - lv_obj_t *startButton; - - - - - protected: - public: - ScreenWelcome(void (*startCallback)(lv_event_t *e)){ - //Set set the "instruction" - lv_label_set_text(instructionLabel, "Press Start to begin..."); - - - //Add button "Start" - startButton = lv_button_create(buttonsContainer); - lv_obj_add_style(startButton, &buttonDefaultStyle, 0); - lv_obj_t *label = lv_label_create(startButton); - lv_label_set_text(label, "Start"); - lv_obj_add_style(label, &buttonLabelDefaultStyle, 0); - lv_obj_add_event_cb(startButton, startCallback, LV_EVENT_CLICKED, NULL); - } - -}; -#endif diff --git a/src/gui/screenAcceptCash.hpp b/src/gui/screenAcceptCash.hpp @@ -4,15 +4,23 @@ #include "screen.hpp" #include "lvgl.h" #include <src/core/lv_obj_pos.h> +#include <src/misc/lv_types.h> #include <src/widgets/label/lv_label.h> +#include "global.hpp" + class ScreenAcceptCash : public Screen{ private: lv_obj_t *finishButton; lv_obj_t *amountLabel; + + static void finishedButtonEvent(lv_event_t *e){ + eventHandler(EVENT_BUTTON_FINISH_CASHIN); + } + protected: public: - ScreenAcceptCash(char* amountString, void (*finishCallback)(lv_event_t *e)){ + ScreenAcceptCash(char* amountString){ //Set set the "instruction" lv_label_set_text(instructionLabel, "Insert Cash and press Finish if you're done"); @@ -22,7 +30,7 @@ class ScreenAcceptCash : public Screen{ lv_obj_t *label = lv_label_create(finishButton); lv_label_set_text(label, "Finish"); lv_obj_add_style(label, &buttonLabelDefaultStyle, 0); - lv_obj_add_event_cb(finishButton, finishCallback, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(finishButton, finishedButtonEvent, LV_EVENT_CLICKED, NULL); //Add field, displaying amount amountLabel = lv_label_create(mainContentContainer); diff --git a/src/gui/screenConnection.hpp b/src/gui/screenConnection.hpp @@ -1,6 +1,7 @@ #ifndef SCREEN_CONNECTION_H #define SCREEN_CONNECTION_H +#include "global.hpp" #include "screen.hpp" #include <cstring> #include <src/core/lv_obj_pos.h> @@ -12,9 +13,14 @@ class ScreenConnection : public Screen{ private: lv_obj_t *abortButton; lv_obj_t *qrCode; + + static void callbackEventAbort(lv_event_t *e){ + eventHandler(EVENT_BUTTON_ABORT); + } + protected: public: - ScreenConnection(char *uri, void (*abortCallback)(lv_event_t *e)){ + ScreenConnection(){ //Set the "instruction lv_label_set_text(instructionLabel, "Scan the QR-Code with your Taler Wallet App"); @@ -24,14 +30,16 @@ class ScreenConnection : public Screen{ lv_obj_t *label = lv_label_create(abortButton); lv_label_set_text(label, "Abort"); lv_obj_add_style(label, &buttonLabelDefaultStyle, 0); - lv_obj_add_event_cb(abortButton, abortCallback, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(abortButton, callbackEventAbort, LV_EVENT_CLICKED, NULL); //Add QR-Code qrCode = lv_qrcode_create(mainContentContainer); lv_qrcode_set_size(qrCode, LV_PCT(80)); lv_qrcode_set_dark_color(qrCode, lv_color_black()); lv_qrcode_set_light_color(qrCode, lv_color_white()); + } + void generateQR(char* uri){ lv_qrcode_update(qrCode, uri, strlen(uri)); lv_obj_center(qrCode); } diff --git a/src/gui/screenIdentification.hpp b/src/gui/screenIdentification.hpp @@ -5,15 +5,19 @@ #include <src/misc/lv_types.h> #include <src/widgets/label/lv_label.h> - +#include "global.hpp" class ScreenIdentification : public Screen { private: lv_obj_t *abortButton; + + static void abortButtonEvent(lv_event_t *e){ + eventHandler(EVENT_BUTTON_ABORT); + } protected: public: - ScreenIdentification(void (*abortCallback)(lv_event_t *e)){ + ScreenIdentification(){ //Set the instruction lv_label_set_text(instructionLabel, "Identificate presenting a NFC-Tag to the NFC-Reader."); @@ -24,7 +28,7 @@ class ScreenIdentification : public Screen { lv_obj_t *label = lv_label_create(abortButton); lv_label_set_text(label, "Abort"); lv_obj_add_style(label, &buttonLabelDefaultStyle, 0); - lv_obj_add_event_cb(abortButton, abortCallback, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(abortButton, abortButtonEvent, LV_EVENT_CLICKED, NULL); } }; #endif diff --git a/src/gui/screenWelcomme.hpp b/src/gui/screenWelcomme.hpp @@ -2,6 +2,7 @@ #define SCREEN_WELCOME_H #include "screen.hpp" #include <cstdint> +#include <functional> #include <src/core/lv_obj_event.h> #include <src/core/lv_obj_pos.h> #include <src/core/lv_obj_style.h> @@ -11,23 +12,30 @@ #include <src/widgets/button/lv_button.h> #include <src/widgets/label/lv_label.h> +#include "global.hpp" + + class ScreenWelcome : public Screen { private: lv_obj_t *startButton; + + static void startButtonEvent(lv_event_t *e){ + eventHandler(EVENT_BUTTON_START); + } - protected: public: - ScreenWelcome(void (*startCallback)(lv_event_t *e)){ + ScreenWelcome(){ //Set set the "instruction" lv_label_set_text(instructionLabel, "Press Start to begin..."); + //Add button "Start" startButton = lv_button_create(buttonsContainer); lv_obj_add_style(startButton, &buttonDefaultStyle, 0); lv_obj_t *label = lv_label_create(startButton); lv_label_set_text(label, "Start"); lv_obj_add_style(label, &buttonLabelDefaultStyle, 0); - lv_obj_add_event_cb(startButton, startCallback, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(startButton, startButtonEvent, LV_EVENT_CLICKED, NULL); } }; #endif diff --git a/src/include/global.hpp b/src/include/global.hpp @@ -0,0 +1,24 @@ +#ifndef GLOBAL_H +#define GLOBAL_H + +enum event_e { + EVENT_INITIALIZE, + EVENT_BUTTON_START, + EVENT_BUTTON_ABORT, + EVENT_BUTTON_FINISH_CASHIN, + EVENT_WAKEUP, + EVENT_SLEEP, + EVENT_TIMEOUT, + EVENT_IDENTIFICATION_SUCCESS, + EVENT_BANK_TOKEN_DONE, + EVENT_BANK_WITHDRAWAL_DONE, + EVENT_BANK_W_STATUS_CONFIRMED, + EVENT_BANK_W_STATUS_PENDING, + EVENT_BANK_W_CONFIRMATION_DONE, + ENUM_EVENT_END +}; +#define NUMBER_OF_EVENTS 13 + +void eventHandler(event_e event); + +#endif diff --git a/src/include/gui.hpp b/src/include/gui.hpp @@ -1,2 +1,5 @@ #include "../gui/gui.hpp" #include "../gui/screenWelcomme.hpp" +#include "../gui/screenIdentification.hpp" +#include "../gui/screenConnection.hpp" +#include "../gui/screenAcceptCash.hpp"