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 }