cash2ecash

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

cash2ecash.cpp (8587B)


      1 // This is the main function for the cash2ecash program
      2 #include <iostream>
      3 #include <ostream>
      4 #include <vector>
      5 #include <mutex>
      6 #include "cashacceptors.hpp"
      7 #include "utils.hpp"
      8 #include "gui.hpp"
      9 #include "global.hpp"
     10 #include "bank.hpp"
     11 
     12 // Global Definitions
     13 enum state_e {
     14   INIT,
     15   SLEEP,
     16   IDLE,
     17   CONNECTION,
     18   ACCEPTCASH,
     19   DONE,
     20   IDENTIFICATION,
     21   ENUM_STATE_END
     22 };
     23 #define NUMBER_OF_STATES 7
     24 
     25 enum state_e state = INIT;
     26 
     27 const char *withdrawal_id;
     28 const char *taler_withdraw_uri;
     29 
     30 std::vector<event_e> eventFIFO;
     31 std::mutex eventFIFOMutex;
     32 
     33 
     34 char hello[] = "hello";
     35 char world[] = "wold";
     36 char *string = hello;
     37 Gui gui;
     38 Timer withdrawalStatusTimer;
     39 
     40 
     41 ScreenWelcome *screenWelcome = new ScreenWelcome;
     42 ScreenIdentification *screenIdentification = new ScreenIdentification;
     43 ScreenConnection  *screenConnection = new ScreenConnection;
     44 ScreenAcceptCash  *screenAcceptCash = new ScreenAcceptCash(string);
     45 void guiDriver();
     46 BankCommunication bankCommunication;
     47 char serialpath[] = "/dev/ttyAMA3";
     48 DG600F Cashaccepor(serialpath);
     49 TALER_Amount confirmedAmount;
     50 
     51 typedef void(*action_t)();
     52 
     53 typedef struct {
     54   action_t action;
     55   state_e nextState;
     56 } stateEventPair;
     57 
     58 stateEventPair stateEventTable[NUMBER_OF_STATES][NUMBER_OF_EVENTS];
     59 //std::vector< std::vector<stateEventPair> >stateEvent2dVector(6, std::vector<stateEventPair>(4));
     60 
     61 
     62 void actionEventInitialize() {
     63   std::cout << "Event action initialze called" << std::endl;
     64   gui.setActiveScreen(screenWelcome);
     65 }
     66 
     67 void actionEventUnexpected(){
     68   std::cerr << "Event not expected in this state: " << state << std::endl;
     69 }
     70 
     71 void actionEventStart(){
     72   std::cout << "Action Event Start called" << std::endl;
     73   //gui.setActiveScreen(screenIdentification);
     74   gui.setActiveScreen(screenIdentification);
     75 }
     76 
     77 void actionEventAbortIdent(){
     78   std::cout << "Action Event Abort Ident called" << std::endl;
     79   gui.setActiveScreen(screenWelcome);
     80 }
     81 
     82 void actionEventAbortConnection(){
     83   std::cout << "Action Abort Connection called" << std::endl;
     84   gui.setActiveScreen(screenWelcome);
     85 }
     86 
     87 void actionEventFinishCashin(){
     88   std::cout << "Action Event Finish Cashin called" << std::endl;
     89   Cashaccepor.readAccumulated(&confirmedAmount);
     90   Cashaccepor.stopMoneyAcceptance();
     91   bankCommunication.withdrawalConfirmRequest(withdrawal_id, &confirmedAmount);
     92   gui.setActiveScreen(screenWelcome);
     93 }
     94 
     95 void actionEventSleep() { std::cout << "Action Event xx called" << std::endl; }
     96 
     97 void actionEventWakeup() { std::cout << "Action Event xx called" << std::endl; }
     98 
     99 void actionEventIdentificationSuccess(){
    100   std::cout << "Action Event Identification Success called" << std::endl;
    101   gui.setActiveScreen(screenConnection);
    102   bankCommunication.init();
    103 }
    104 
    105 void actionEventBankTokenDone(){
    106   std::cout << "Action Event Bank Token Done called" << std::endl;
    107   //static struct TALER_Amount amountZero;
    108   //TALER_amount_set_zero("KUDOS", &amountZero);
    109   //amountZero.fraction = 5000000;
    110   static bool noAmountToWallet = true;
    111   bankCommunication.withdrawalRequest(NULL, NULL, &noAmountToWallet, &withdrawal_id, &taler_withdraw_uri);
    112 }
    113 
    114 void actionEventBankWithdrawalDone(){
    115   std::cout << "Action Event Bank Withdrawal Done called" << std::endl;
    116   screenConnection->generateQR(taler_withdraw_uri);
    117   bankCommunication.withrawalStatusRequest(withdrawal_id);
    118 }
    119 
    120 void actionEventBankWStatusSelected(){
    121   std::cout << "Action Event Bank Withdrawal Status Confirmed called" << std::endl;
    122   gui.setActiveScreen(screenAcceptCash);
    123   Cashaccepor.startMoneyAcceptance();
    124 }
    125 
    126 void actionEventBankWStatusPending(){
    127   std::cout << "Action Event Bank Withdrawal Status Pending called" << std::endl;
    128   bankCommunication.withrawalStatusRequest(withdrawal_id);
    129 }
    130 
    131 void actionEventWConfirmationDone(){
    132   std::cout << "Action Event Bank Confirmation Done called" << std::endl;
    133   gui.setActiveScreen(screenWelcome);
    134 }
    135 
    136 void actionEventIdentificationTimeout(){
    137   std::cout << "Action Event Identification Timeout called" << std::endl;
    138   gui.setActiveScreen(screenWelcome);
    139 }
    140 
    141 void actionEventAcceptCashTimeout(){
    142   std::cout << "Action Event Acceptcash Timeout called" << std::endl;
    143   Cashaccepor.readAccumulated(&confirmedAmount);
    144   Cashaccepor.stopMoneyAcceptance();
    145   bankCommunication.withdrawalConfirmRequest(withdrawal_id, &confirmedAmount);
    146 }
    147 
    148 void actionEventConnectionTimeout(){
    149   std::cout << "Action Event Connection Timeout called" << std::endl;
    150   gui.setActiveScreen(screenWelcome);
    151 }
    152 
    153 void actionEventDoneTimeout() {
    154   std::cout << "Action Event Done Timeout called" << std::endl;
    155   gui.setActiveScreen(screenWelcome);
    156 }
    157 
    158 
    159 
    160 
    161 void initStateEvent(){
    162   //Runtime initialzation is used due to convienient array indexing.
    163   //Initzialize all state-event pairs to handleuUnexpectedEvent
    164   int state, event;
    165   for (state = 0; state < ENUM_STATE_END; state++) {
    166     for (event = 0; event < ENUM_EVENT_END; event++) {
    167       stateEventTable[state][event].action = &actionEventUnexpected;
    168       stateEventTable[state][event].nextState = (state_e)state;
    169     }
    170   }
    171 
    172   //Overwrite desired state-event pairs to provide actual functionality
    173   stateEventTable[INIT][EVENT_INITIALIZE].action = actionEventInitialize;
    174   stateEventTable[INIT][EVENT_INITIALIZE].nextState = IDLE;
    175   stateEventTable[IDLE][EVENT_BUTTON_START].action = actionEventStart;
    176   stateEventTable[IDLE][EVENT_BUTTON_START].nextState = IDENTIFICATION; //needs to be changed to initialization later
    177   stateEventTable[IDLE][EVENT_SLEEP].action = actionEventSleep;
    178   stateEventTable[IDLE][EVENT_SLEEP].nextState = SLEEP;
    179   
    180   stateEventTable[SLEEP][EVENT_WAKEUP].action = actionEventWakeup;
    181   stateEventTable[SLEEP][EVENT_WAKEUP].nextState = IDLE;
    182   
    183   stateEventTable[IDENTIFICATION][EVENT_BUTTON_ABORT].action = actionEventAbortIdent;
    184   stateEventTable[IDENTIFICATION][EVENT_BUTTON_ABORT].nextState = IDLE;
    185   stateEventTable[IDENTIFICATION][EVENT_IDENTIFICATION_SUCCESS].action = actionEventIdentificationSuccess;
    186   stateEventTable[IDENTIFICATION][EVENT_IDENTIFICATION_SUCCESS].nextState = CONNECTION;
    187   stateEventTable[IDENTIFICATION][EVENT_TIMEOUT].action = actionEventIdentificationTimeout;
    188   stateEventTable[IDENTIFICATION][EVENT_TIMEOUT].nextState = IDLE;
    189 
    190   stateEventTable[CONNECTION][EVENT_BUTTON_ABORT].action = actionEventAbortConnection;
    191   stateEventTable[CONNECTION][EVENT_BUTTON_ABORT].nextState = IDLE;
    192   stateEventTable[CONNECTION][EVENT_BANK_TOKEN_DONE].action = actionEventBankTokenDone;
    193   stateEventTable[CONNECTION][EVENT_BANK_TOKEN_DONE].nextState = CONNECTION;
    194   stateEventTable[CONNECTION][EVENT_BANK_WITHDRAWAL_DONE].action = actionEventBankWithdrawalDone;
    195   stateEventTable[CONNECTION][EVENT_BANK_WITHDRAWAL_DONE].nextState = CONNECTION;
    196   stateEventTable[CONNECTION][EVENT_BANK_W_STATUS_PENDING].action = actionEventBankWStatusPending;
    197   stateEventTable[CONNECTION][EVENT_BANK_W_STATUS_PENDING].nextState = CONNECTION;
    198   stateEventTable[CONNECTION][EVENT_BANK_W_STATUS_SELECTED].action = actionEventBankWStatusSelected;
    199   stateEventTable[CONNECTION][EVENT_BANK_W_STATUS_SELECTED].nextState = ACCEPTCASH;
    200   stateEventTable[CONNECTION][EVENT_TIMEOUT].action = actionEventConnectionTimeout;
    201   stateEventTable[CONNECTION][EVENT_TIMEOUT].nextState = IDLE;
    202   
    203   stateEventTable[ACCEPTCASH][EVENT_BUTTON_FINISH_CASHIN].action = actionEventFinishCashin;
    204   stateEventTable[ACCEPTCASH][EVENT_BUTTON_FINISH_CASHIN].nextState = DONE;
    205   stateEventTable[ACCEPTCASH][EVENT_TIMEOUT].action = actionEventAcceptCashTimeout;
    206   stateEventTable[ACCEPTCASH][EVENT_TIMEOUT].nextState = DONE;
    207   stateEventTable[DONE][EVENT_TIMEOUT].action = actionEventDoneTimeout;
    208   stateEventTable[DONE][EVENT_TIMEOUT].nextState = IDLE;
    209 }
    210 
    211 
    212 void event(event_e event){
    213   eventFIFOMutex.lock();
    214   eventFIFO.push_back(event);
    215   eventFIFOMutex.unlock();
    216 }
    217 
    218 void eventHandler(){
    219   state_e oldstate;
    220   event_e event;
    221   eventFIFOMutex.lock();
    222   while (0 < eventFIFO.size()) {
    223     oldstate = state;
    224     event = eventFIFO.front();
    225     eventFIFOMutex.unlock();
    226     state = stateEventTable[state][event].nextState;
    227     stateEventTable[oldstate][event].action();
    228     eventFIFOMutex.lock();
    229     eventFIFO.erase(eventFIFO.begin());
    230   }
    231   eventFIFOMutex.unlock();
    232 }
    233 
    234 int main(int argc, char *argv[]){
    235   
    236   std::cout << "The Program is running" <<std::endl;
    237   Timer timer1;
    238   timer1.setTimeMillis(10000);
    239   TALER_Amount testamount;
    240 
    241   //Initialize State Machine
    242   initStateEvent();
    243   
    244   //Trigger Initialzation Event
    245   event(EVENT_INITIALIZE);
    246   
    247   while (true) {
    248     guiDriver();
    249     eventHandler();
    250   }
    251 }
    252 
    253 
    254 void guiDriver(){
    255   static Timer guiSleep;
    256   if (guiSleep.over()){
    257     guiSleep.setTimeMillis(gui.timerHandler());
    258     guiSleep.start();
    259   }
    260 }