From ca01734e7a5b3c12ae70e73c0b247f39771aaa97 Mon Sep 17 00:00:00 2001 From: Bernard Blackham Date: Fri, 29 Feb 2008 13:25:50 +0000 Subject: [PATCH] Work from tonight: MIFARE integration. Old DAA patches for balance showing. Eat easter eggs. --- sql-edition/servers/VendServer.py | 81 +++++++++++++-------------- sql-edition/servers/VendingMachine.py | 31 ++++++++-- 2 files changed, 65 insertions(+), 47 deletions(-) diff --git a/sql-edition/servers/VendServer.py b/sql-edition/servers/VendServer.py index eff58e0..fa5ba5b 100755 --- a/sql-edition/servers/VendServer.py +++ b/sql-edition/servers/VendServer.py @@ -43,6 +43,7 @@ DOOR = 1 SWITCH = 2 KEY = 3 TICK = 4 +MIFARE = 5 ( @@ -55,7 +56,7 @@ STATE_GET_SELECTION, STATE_GRANDFATHER_CLOCK, ) = range(1,8) -TEXT_SPEED = 0.8 +TEXT_SPEED = 0.6 IDLE_SPEED = 0.05 class DispenseDatabaseException(Exception): pass @@ -91,8 +92,14 @@ class DispenseDatabase: def scroll_options(username, mk, welcome = False): if welcome: + # Balance checking: crap code, [DAA]'s fault + acct = os.popen('dispense acct %s' % username) + balance = acct.read()[15:22] + acct.close() + msg = [(center('WELCOME'), False, TEXT_SPEED), - (center(username), False, TEXT_SPEED)] + (center(username), False, TEXT_SPEED), + (center(balance), False, TEXT_SPEED),] else: msg = [] choices = ' '*10+'CHOICES: ' @@ -157,8 +164,8 @@ def get_pin(uid): def has_good_pin(uid): return get_pin(uid) != None -def verify_user_pin(uid, pin): - if get_pin(uid) == pin: +def verify_user_pin(uid, pin, skip_pin_check=False): + if skip_pin_check or get_pin(uid) == pin: info = pwd.getpwuid(uid) logging.info('accepted pin for uid %d (%s)'%(uid,info.pw_name)) return info.pw_name @@ -514,45 +521,9 @@ def handle_getting_uid_key(state, event, params, v, vstatus): else: vstatus.mk.set_message('UID: '+vstatus.cur_user) - - # Easter egg for nikita's birthday -- DGB - if len(vstatus.cur_user) == 8: - if vstatus.cur_user != "07051980": - vstatus.mk.set_messages( - [(' '*9+'ONE MORE TRY NiKiTa'+' '*10, False, 3)]) - vstatus.cur_user = '' - reset_idler(v, vstatus, 3) - return - - # Do stuff here - vstatus.mk.set_messages( - [(center(' GUILD MAILBOX NUMBER 64 '), False, 20), - (center(' GUILD MAILBOX NUMBER 64 '), False, 20), - (center(' GUILD MAILBOX NUMBER 64 '), False, 20), - (center(' GUILD MAILBOX NUMBER 64 '), False, 20)]) - - # Reset - vstatus.cur_user = '' - vstatus.cur_pin = '' - #reset_idler(v, vstatus, 10) - reset_idler(v, vstatus, 2) - return - # End easter egg part 1 if len(vstatus.cur_user) == 5: uid = int(vstatus.cur_user) - # Easter egg for nikita's birthday -- DGB - if vstatus.cur_user == '07051': - if key == 11: - vstatus.cur_user = '' - reset_idler(v, vstatus) - return -# vstatus.cur_user += chr(key + ord('0')) - logging.info(' == 5 dob: '+vstatus.cur_user) - vstatus.mk.set_message('>'+vstatus.cur_user) - return - # end easter egg part 2 - if uid == 0: logging.info('user '+vstatus.cur_user+' has a bad PIN') pfalken=""" @@ -782,6 +753,28 @@ def handle_door_event(state, event, params, v, vstatus): logging.warning('Leaving open door mode') v.display("-YUM YUM!-") +def handle_mifare_event(state, event, params, v, vstatus): + card_uid = params + # Translate card_id into uid. + vstatus.cur_user = str(card_uid) + vstatus.username = verify_user_pin(int(card_uid), None, True) + if vstatus.username: + v.beep(0, False) + vstatus.cur_selection = '' + vstatus.change_state(STATE_GET_SELECTION) + scroll_options(vstatus.username, vstatus.mk, True) + return + else: + v.beep(40, False) + vstatus.mk.set_messages( + [(center('BAD CARD'), False, 1.0), + (center('SORRY'), False, 0.5)]) + vstatus.cur_user = '' + vstatus.cur_pin = '' + + reset_idler(v, vstatus, 2) + return + def return_to_idle(state,event,params,v,vstatus): reset_idler(v, vstatus) @@ -789,26 +782,32 @@ def create_state_table(vstatus): vstatus.state_table[(STATE_IDLE,TICK,1)] = handle_idle_tick vstatus.state_table[(STATE_IDLE,KEY,1)] = handle_idle_key vstatus.state_table[(STATE_IDLE,DOOR,1)] = handle_door_event + vstatus.state_table[(STATE_IDLE,MIFARE,1)] = handle_mifare_event vstatus.state_table[(STATE_DOOR_OPENING,TICK,1)] = handle_door_idle vstatus.state_table[(STATE_DOOR_OPENING,DOOR,1)] = handle_door_event vstatus.state_table[(STATE_DOOR_OPENING,KEY,1)] = do_nothing + vstatus.state_table[(STATE_DOOR_OPENING,MIFARE,1)] = do_nothing vstatus.state_table[(STATE_DOOR_CLOSING,TICK,1)] = return_to_idle vstatus.state_table[(STATE_DOOR_CLOSING,DOOR,1)] = handle_door_event vstatus.state_table[(STATE_DOOR_CLOSING,KEY,1)] = do_nothing + vstatus.state_table[(STATE_DOOR_CLOSING,MIFARE,1)] = do_nothing vstatus.state_table[(STATE_GETTING_UID,TICK,1)] = handle_getting_uid_idle vstatus.state_table[(STATE_GETTING_UID,DOOR,1)] = do_nothing vstatus.state_table[(STATE_GETTING_UID,KEY,1)] = handle_getting_uid_key + vstatus.state_table[(STATE_GETTING_UID,MIFARE,1)] = handle_mifare_event vstatus.state_table[(STATE_GETTING_PIN,TICK,1)] = handle_getting_pin_idle vstatus.state_table[(STATE_GETTING_PIN,DOOR,1)] = do_nothing vstatus.state_table[(STATE_GETTING_PIN,KEY,1)] = handle_getting_pin_key + vstatus.state_table[(STATE_GETTING_PIN,MIFARE,1)] = handle_mifare_event vstatus.state_table[(STATE_GET_SELECTION,TICK,1)] = handle_get_selection_idle vstatus.state_table[(STATE_GET_SELECTION,DOOR,1)] = do_nothing vstatus.state_table[(STATE_GET_SELECTION,KEY,1)] = handle_get_selection_key + vstatus.state_table[(STATE_GET_SELECTION,MIFARE,1)] = do_nothing vstatus.state_table[(STATE_GRANDFATHER_CLOCK,TICK,1)] = handle_idle_grandfather_tick vstatus.state_table[(STATE_GRANDFATHER_CLOCK,TICK,2)] = handle_grandfather_tick @@ -816,6 +815,7 @@ def create_state_table(vstatus): vstatus.state_table[(STATE_GRANDFATHER_CLOCK,DOOR,2)] = do_nothing vstatus.state_table[(STATE_GRANDFATHER_CLOCK,KEY,1)] = do_nothing vstatus.state_table[(STATE_GRANDFATHER_CLOCK,KEY,2)] = do_nothing + vstatus.state_table[(STATE_GRANDFATHER_CLOCK,MIFARE,1)] = handle_mifare_event def get_state_table_handler(vstatus, state, event, counter): return vstatus.state_table[(state,event,counter)] @@ -858,7 +858,6 @@ def run_forever(rfh, wfh, options, cf): except DispenseDatabaseException, e: logging.error('Database error: '+str(e)) - timeout = time_to_next_update(vstatus) e = v.next_event(timeout) (event, params) = e diff --git a/sql-edition/servers/VendingMachine.py b/sql-edition/servers/VendingMachine.py index d73eb4b..aca860e 100644 --- a/sql-edition/servers/VendingMachine.py +++ b/sql-edition/servers/VendingMachine.py @@ -4,6 +4,7 @@ from CRC import do_crc from select import select import socket, logging from time import time, sleep +from MIFAREClient import MIFAREClient asynchronous_responses = [ '400', '401', # door open/closed '610', # switches changed @@ -14,6 +15,7 @@ DOOR = 1 SWITCH = 2 KEY = 3 TICK = 4 +MIFARE = 5 class VendingException(Exception): pass @@ -35,6 +37,7 @@ class VendingMachine: while code != '000': code = self.get_response()[0] self.get_switches() + self.mifare = MIFAREClient() def await_prompt(self): self.wfh.flush() @@ -161,15 +164,31 @@ class VendingMachine: def next_event(self, timeout = None): # we don't want to buffer in the serial port, so we get all the events # we can ASAP. - if timeout < 0: timeout = 0 - if len(self.events) > 0: timeout = 0 - while True: - (r, _, _) = select([self.rfh], [], [], timeout) + + # Never have no timeout... + if timeout == None: timeout = 60*60*24*365 + + # Make sure we go through the loop at least once. + if timeout <= 0: timeout = 0.01 + + while timeout > 0: + this_timeout = min(timeout, 0.2) + timeout -= this_timeout + + (r, _, _) = select([self.rfh], [], [], this_timeout) if r: self.get_response(async = True) timeout = 0 - else: - break + + try: + mifare_uid = self.mifare.get_card_uid() + except ValueError: + mifare_uid = None + if mifare_uid != None: + logging.info('Got MIFARE uid %s'%(str(mifare_uid))) + self.events.append((MIFARE, mifare_uid)) + timeout = 0 + if len(self.events) == 0: return (TICK, time()) ret = self.events[0] del self.events[0] -- 2.20.1