@ -7,13 +7,13 @@ import configreader
@@ -7,13 +7,13 @@ import configreader
class DialConfiguration ( object ) :
def __init__ ( self , dial_timeout , shortcuts , blacklist ) :
self . dial_timeout = dial_timeout
self . shortcuts = shortcuts
self . blacklist = blacklist
def __init__ ( self , dial_timeout , shortcuts , blacklist ) :
self . dial_timeout = dial_timeout
self . shortcuts = shortcuts
self . blacklist = blacklist
class IllegalEventError ( Exception ) :
pass
pass
"""
@ -21,47 +21,47 @@ An abstract state, needed to define all possible events.
@@ -21,47 +21,47 @@ An abstract state, needed to define all possible events.
"""
class AbstractState ( object ) :
def on_registration_in_progress ( self ) :
raise IllegalEventError ( )
def on_registration_in_progress ( self ) :
raise IllegalEventError ( )
def on_registration_successful ( self ) :
raise IllegalEventError ( )
def on_registration_successful ( self ) :
raise IllegalEventError ( )
def on_registration_lost ( self ) :
raise IllegalEventError ( )
def on_registration_lost ( self ) :
raise IllegalEventError ( )
def on_gabelschalter_up ( self ) :
raise IllegalEventError ( )
def on_gabelschalter_up ( self ) :
raise IllegalEventError ( )
def on_gabelschalter_down ( self ) :
raise IllegalEventError ( )
def on_gabelschalter_down ( self ) :
raise IllegalEventError ( )
def on_incoming_call ( self ) :
raise IllegalEventError ( )
def on_incoming_call ( self ) :
raise IllegalEventError ( )
def on_call_ended ( self ) :
raise IllegalEventError ( )
def on_call_ended ( self ) :
raise IllegalEventError ( )
def on_call_accepted ( self ) :
raise IllegalEventError ( )
def on_call_accepted ( self ) :
raise IllegalEventError ( )
def on_call_ringing ( self ) :
raise IllegalEventError ( )
def on_call_ringing ( self ) :
raise IllegalEventError ( )
def on_invalid_number ( self ) :
raise IllegalEventError ( )
def on_invalid_number ( self ) :
raise IllegalEventError ( )
def on_nummernschalter_active ( self ) :
raise IllegalEventError ( )
def on_nummernschalter_active ( self ) :
raise IllegalEventError ( )
def on_nummernschalter_input ( self , num ) :
raise IllegalEventError ( )
def on_nummernschalter_input ( self , num ) :
raise IllegalEventError ( )
def on_timeout ( self ) :
raise IllegalEventError ( )
def on_timeout ( self ) :
raise IllegalEventError ( )
def leave ( self ) :
return None
def leave ( self ) :
return None
"""
@ -70,338 +70,338 @@ behaviour for some events (overriden if necessary).
@@ -70,338 +70,338 @@ behaviour for some events (overriden if necessary).
"""
class BaseState ( AbstractState ) :
def __init__ ( self , controller ) :
self . _controller = controller
def __init__ ( self , controller ) :
self . _controller = controller
def on_registration_lost ( self ) :
return InitState
def on_registration_lost ( self ) :
return InitState
def on_gabelschalter_up ( self ) :
return None
def on_gabelschalter_up ( self ) :
return None
def on_gabelschalter_down ( self ) :
return None
def on_gabelschalter_down ( self ) :
return None
def on_incoming_call ( self ) :
self . _controller . phone . decline_call ( )
def on_incoming_call ( self ) :
self . _controller . phone . decline_call ( )
def on_call_ended ( self ) :
# When an incoming call is declined, a call_ended event occurs, which
# needs to be ignored, here.
return None
def on_call_ended ( self ) :
# When an incoming call is declined, a call_ended event occurs, which
# needs to be ignored, here.
return None
def on_nummernschalter_active ( self ) :
return None
def on_nummernschalter_active ( self ) :
return None
def on_nummernschalter_input ( self , num ) :
return None
def on_nummernschalter_input ( self , num ) :
return None
class InitState ( BaseState ) :
def __init__ ( self , controller ) :
super ( InitState , self ) . __init__ ( controller )
self . _controller . feap . set_schauzeichen ( True )
def __init__ ( self , controller ) :
super ( InitState , self ) . __init__ ( controller )
self . _controller . feap . set_schauzeichen ( True )
def on_registration_in_progress ( self ) :
print ( ' registration in progress ' )
return RegisteringState
def on_registration_in_progress ( self ) :
print ( ' registration in progress ' )
return RegisteringState
class RegisteringState ( BaseState ) :
def __init__ ( self , controller ) :
super ( RegisteringState , self ) . __init__ ( controller )
def __init__ ( self , controller ) :
super ( RegisteringState , self ) . __init__ ( controller )
def on_registration_successful ( self ) :
print ( ' registration successful ' )
self . _controller . feap . set_schauzeichen ( False )
return IdleState
def on_registration_successful ( self ) :
print ( ' registration successful ' )
self . _controller . feap . set_schauzeichen ( False )
return IdleState
class IdleState ( BaseState ) :
def on_incoming_call ( self ) :
print ( ' incomfing call ' )
caller = self . _controller . phone . get_remote_number ( )
print ( ' From: %s ' % caller )
if caller in self . _controller . dialconfig . blacklist :
print ( ' Caller on blacklist - declining ' )
self . _controller . phone . decline_call ( )
return CallTerminatingState
else :
return SchelltState
def on_gabelschalter_up ( self ) :
print ( ' gabel up ' )
return DialingState
def on_incoming_call ( self ) :
print ( ' incomfing call ' )
caller = self . _controller . phone . get_remote_number ( )
print ( ' From: %s ' % caller )
if caller in self . _controller . dialconfig . blacklist :
print ( ' Caller on blacklist - declining ' )
self . _controller . phone . decline_call ( )
return CallTerminatingState
else :
return SchelltState
def on_gabelschalter_up ( self ) :
print ( ' gabel up ' )
return DialingState
class SchelltState ( BaseState ) :
def __init__ ( self , controller ) :
super ( SchelltState , self ) . __init__ ( controller )
self . _controller . feap . set_wecker ( True )
def __init__ ( self , controller ) :
super ( SchelltState , self ) . __init__ ( controller )
self . _controller . feap . set_wecker ( True )
def leave ( self ) :
self . _controller . feap . set_wecker ( False )
def leave ( self ) :
self . _controller . feap . set_wecker ( False )
def on_gabelschalter_up ( self ) :
return AcceptingState
def on_gabelschalter_up ( self ) :
return AcceptingState
def on_call_ended ( self ) :
return IdleState
def on_call_ended ( self ) :
return IdleState
class AcceptingState ( BaseState ) :
def __init__ ( self , controller ) :
super ( AcceptingState , self ) . __init__ ( controller )
self . _controller . phone . accept_call ( )
def __init__ ( self , controller ) :
super ( AcceptingState , self ) . __init__ ( controller )
self . _controller . phone . accept_call ( )
def on_call_accepted ( self ) :
return CallRunningState
def on_call_accepted ( self ) :
return CallRunningState
class CallTerminatingState ( BaseState ) :
def __init__ ( self , controller ) :
super ( CallTerminatingState , self ) . __init__ ( controller )
self . _controller . phone . end_call ( )
def __init__ ( self , controller ) :
super ( CallTerminatingState , self ) . __init__ ( controller )
self . _controller . phone . end_call ( )
def on_call_ended ( self ) :
return IdleState
def on_call_ended ( self ) :
return IdleState
def on_call_accepted ( self ) :
return None
def on_call_accepted ( self ) :
return None
class ForgottenState ( BaseState ) :
def on_gabelschalter_down ( self ) :
return IdleState
def on_gabelschalter_down ( self ) :
return IdleState
class BusyBeepingState ( BaseState ) :
def __init__ ( self , controller ) :
super ( BusyBeepingState , self ) . __init__ ( controller )
self . _controller . phone . play_busy_tone ( )
def __init__ ( self , controller ) :
super ( BusyBeepingState , self ) . __init__ ( controller )
self . _controller . phone . play_busy_tone ( )
def leave ( self ) :
self . _controller . phone . stop_playing ( )
def leave ( self ) :
self . _controller . phone . stop_playing ( )
def on_timeout ( self ) :
return ForgottenState
def on_timeout ( self ) :
return ForgottenState
def on_gabelschalter_down ( self ) :
return IdleState
def on_gabelschalter_down ( self ) :
return IdleState
class CallRunningState ( BaseState ) :
def on_gabelschalter_down ( self ) :
return CallTerminatingState
def on_gabelschalter_down ( self ) :
return CallTerminatingState
def on_call_ended ( self ) :
return BusyBeepingState
def on_call_ended ( self ) :
return BusyBeepingState
class WecktState ( BaseState ) :
def __init__ ( self , controller ) :
super ( WecktState , self ) . __init__ ( controller )
self . _controller . phone . play_ringback_tone ( )
def __init__ ( self , controller ) :
super ( WecktState , self ) . __init__ ( controller )
self . _controller . phone . play_ringback_tone ( )
def leave ( self ) :
self . _controller . phone . stop_playing ( )
def leave ( self ) :
self . _controller . phone . stop_playing ( )
def on_gabelschalter_down ( self ) :
return CallTerminatingState
def on_gabelschalter_down ( self ) :
return CallTerminatingState
def on_call_ended ( self ) :
return BusyBeepingState
def on_call_ended ( self ) :
return BusyBeepingState
def on_call_accepted ( self ) :
return CallRunningState
def on_call_accepted ( self ) :
return CallRunningState
class ConnectingState ( BaseState ) :
def on_gabelschalter_down ( self ) :
return CallTerminatingState
def on_gabelschalter_down ( self ) :
return CallTerminatingState
def on_call_ringing ( self ) :
return WecktState
def on_call_ringing ( self ) :
return WecktState
def on_call_accepted ( self ) :
return CallRunningState
def on_call_accepted ( self ) :
return CallRunningState
def on_invalid_number ( self ) :
# TODO: play sound
return BusyBeepingState
def on_invalid_number ( self ) :
# TODO: play sound
return BusyBeepingState
def on_call_ended ( self ) :
return BusyBeepingState
def on_call_ended ( self ) :
return BusyBeepingState
class DialingState ( BaseState ) :
def __init__ ( self , controller ) :
super ( DialingState , self ) . __init__ ( controller )
self . _controller . phone . play_dial_tone ( )
self . __dial_tone = True
self . __number = ' '
def leave ( self ) :
if self . __dial_tone :
self . _controller . phone . stop_playing ( )
self . _controller . abort_timeout ( )
def on_gabelschalter_down ( self ) :
return IdleState
def on_nummernschalter_active ( self ) :
self . _controller . abort_timeout ( )
if self . __dial_tone :
self . _controller . phone . stop_playing ( )
def on_nummernschalter_input ( self , num ) :
print ( ' nummernschalter: %d ' % ( num ) )
if self . __dial_tone :
self . _controller . phone . stop_playing ( )
self . __number + = str ( num )
self . _controller . abort_timeout ( )
self . _controller . set_timeout ( self . _controller . dialconfig . dial_timeout * 1000 )
self . _controller . phone . read_text ( str ( num ) )
def on_timeout ( self ) :
number = self . __number
print ' Dialing number: ' , number
if number in self . _controller . dialconfig . shortcuts :
number = self . _controller . dialconfig . shortcuts [ number ]
print ' shortcut resolved: ' , number
self . _controller . phone . call ( number )
return ConnectingState
def __init__ ( self , controller ) :
super ( DialingState , self ) . __init__ ( controller )
self . _controller . phone . play_dial_tone ( )
self . __dial_tone = True
self . __number = ' '
def leave ( self ) :
if self . __dial_tone :
self . _controller . phone . stop_playing ( )
self . _controller . abort_timeout ( )
def on_gabelschalter_down ( self ) :
return IdleState
def on_nummernschalter_active ( self ) :
self . _controller . abort_timeout ( )
if self . __dial_tone :
self . _controller . phone . stop_playing ( )
def on_nummernschalter_input ( self , num ) :
print ( ' nummernschalter: %d ' % ( num ) )
if self . __dial_tone :
self . _controller . phone . stop_playing ( )
self . __number + = str ( num )
self . _controller . abort_timeout ( )
self . _controller . set_timeout ( self . _controller . dialconfig . dial_timeout * 1000 )
self . _controller . phone . read_text ( str ( num ) )
def on_timeout ( self ) :
number = self . __number
print ' Dialing number: ' , number
if number in self . _controller . dialconfig . shortcuts :
number = self . _controller . dialconfig . shortcuts [ number ]
print ' shortcut resolved: ' , number
self . _controller . phone . call ( number )
return ConnectingState
class StateMachineController ( object ) :
def __init__ ( self , phone , feap , dialconfig ) :
self . __phone = phone
self . __feap = feap
self . __dialconfig = dialconfig
self . __state = InitState ( self )
self . __timeout = None
self . __running = True
self . __evqueue = queue . Queue ( )
self . __evthread = threading . Thread ( target = self . __event_dispatcher )
self . __evthread . start ( )
def __event_dispatcher ( self ) :
while self . __running :
( evname , evargs , evkwargs ) = self . __evqueue . get ( )
if not evname :
return
print ( ' !!! event: %s ' % ( evname ) )
handler = getattr ( self . __state , ' on_ %s ' % ( evname ) )
try :
newstate = handler ( * evargs , * * evkwargs )
except IllegalEventError :
print ( ' illegal event occured!!!!!!!!!!!!!!!!!!!! ' , self . __state . __class__ . __name__ )
if not newstate :
continue
self . __state . leave ( )
self . abort_timeout ( )
oldstate = self . __state . __class__
print ( ' %s -> %s ' % ( oldstate . __name__ , newstate . __name__ ) )
self . __state = newstate ( self )
def queue_event ( self , evname , * evargs , * * evkwargs ) :
if not hasattr ( AbstractState , ' on_ %s ' % ( evname ) ) :
raise ValueError ( ' Illegal event name: %s ' % ( evname ) )
self . __evqueue . put ( ( evname , evargs , evkwargs ) )
def set_timeout ( self , timeout ) :
self . __timeout = threading . Timer ( timeout / 1000 , self . queue_event , args = [ ' timeout ' ] )
self . __timeout . start ( )
def abort_timeout ( self ) :
if self . __timeout :
self . __timeout . cancel ( )
self . __timeout = None
@property
def phone ( self ) :
return self . __phone
@property
def feap ( self ) :
return self . __feap
@property
def dialconfig ( self ) :
return self . __dialconfig
def stop ( self , hard = False ) :
if hard :
self . __running = False
self . __evqueue . put ( ( None , None , None ) )
def __init__ ( self , phone , feap , dialconfig ) :
self . __phone = phone
self . __feap = feap
self . __dialconfig = dialconfig
self . __state = InitState ( self )
self . __timeout = None
self . __running = True
self . __evqueue = queue . Queue ( )
self . __evthread = threading . Thread ( target = self . __event_dispatcher )
self . __evthread . start ( )
def __event_dispatcher ( self ) :
while self . __running :
( evname , evargs , evkwargs ) = self . __evqueue . get ( )
if not evname :
return
print ( ' !!! event: %s ' % ( evname ) )
handler = getattr ( self . __state , ' on_ %s ' % ( evname ) )
try :
newstate = handler ( * evargs , * * evkwargs )
except IllegalEventError :
print ( ' illegal event occured!!!!!!!!!!!!!!!!!!!! ' , self . __state . __class__ . __name__ )
if not newstate :
continue
self . __state . leave ( )
self . abort_timeout ( )
oldstate = self . __state . __class__
print ( ' %s -> %s ' % ( oldstate . __name__ , newstate . __name__ ) )
self . __state = newstate ( self )
def queue_event ( self , evname , * evargs , * * evkwargs ) :
if not hasattr ( AbstractState , ' on_ %s ' % ( evname ) ) :
raise ValueError ( ' Illegal event name: %s ' % ( evname ) )
self . __evqueue . put ( ( evname , evargs , evkwargs ) )
def set_timeout ( self , timeout ) :
self . __timeout = threading . Timer ( timeout / 1000 , self . queue_event , args = [ ' timeout ' ] )
self . __timeout . start ( )
def abort_timeout ( self ) :
if self . __timeout :
self . __timeout . cancel ( )
self . __timeout = None
@property
def phone ( self ) :
return self . __phone
@property
def feap ( self ) :
return self . __feap
@property
def dialconfig ( self ) :
return self . __dialconfig
def stop ( self , hard = False ) :
if hard :
self . __running = False
self . __evqueue . put ( ( None , None , None ) )
c = None
def gabelschalter_cb ( state ) :
global c
if state == 1 :
c . queue_event ( ' gabelschalter_up ' )
else :
c . queue_event ( ' gabelschalter_down ' )
global c
if state == 1 :
c . queue_event ( ' gabelschalter_up ' )
else :
c . queue_event ( ' gabelschalter_down ' )
def nummernschalter_active_cb ( ) :
global c
c . queue_event ( ' nummernschalter_active ' )
global c
c . queue_event ( ' nummernschalter_active ' )
def nummernschalter_done_cb ( digit ) :
global c
c . queue_event ( ' nummernschalter_input ' , digit )
global c
c . queue_event ( ' nummernschalter_input ' , digit )
def phone_cb ( event ) :
if event == PhoneEvent . RegInProgress :
c . queue_event ( ' registration_in_progress ' )
elif event == PhoneEvent . RegSuccessfull :
c . queue_event ( ' registration_successful ' )
elif event == PhoneEvent . RegLost :
c . queue_event ( ' registration_lost ' )
elif event == PhoneEvent . CallIncoming :
c . queue_event ( ' incoming_call ' )
elif event == PhoneEvent . CallAccepted :
c . queue_event ( ' call_accepted ' )
elif event == PhoneEvent . CallEnded :
c . queue_event ( ' call_ended ' )
elif event == PhoneEvent . CallRinging :
c . queue_event ( ' call_ringing ' )
elif event == PhoneEvent . CallBusy :
c . queue_event ( ' call_ended ' )
elif event == PhoneEvent . CallInvalidNumber :
c . queue_event ( ' invalid_number ' )
if event == PhoneEvent . RegInProgress :
c . queue_event ( ' registration_in_progress ' )
elif event == PhoneEvent . RegSuccessfull :
c . queue_event ( ' registration_successful ' )
elif event == PhoneEvent . RegLost :
c . queue_event ( ' registration_lost ' )
elif event == PhoneEvent . CallIncoming :
c . queue_event ( ' incoming_call ' )
elif event == PhoneEvent . CallAccepted :
c . queue_event ( ' call_accepted ' )
elif event == PhoneEvent . CallEnded :
c . queue_event ( ' call_ended ' )
elif event == PhoneEvent . CallRinging :
c . queue_event ( ' call_ringing ' )
elif event == PhoneEvent . CallBusy :
c . queue_event ( ' call_ended ' )
elif event == PhoneEvent . CallInvalidNumber :
c . queue_event ( ' invalid_number ' )
if __name__ == ' __main__ ' :
cfg = configreader . ConfigurationReader ( )
cfg . read ( ' fetap.ini ' )
phone = PhoneInterface ( cfg . phoneconfig )
feap = FeApUserInterface ( cfg . pinconfig )
c = StateMachineController ( phone , feap , cfg . dialconfig )
feap . add_gabelschalter_callback ( gabelschalter_cb )
feap . add_nummernschalter_active_callback ( nummernschalter_active_cb )
feap . add_nummernschalter_done_callback ( nummernschalter_done_cb )
phone . add_event_cb ( phone_cb )
phone . start ( )
try :
while True :
time . sleep ( 1 )
'''
c . queue_event ( ' gabelschalter_up ' )
c . queue_event ( ' nummernschalter_input ' , 4 )
c . queue_event ( ' nummernschalter_input ' , 2 )
#c.queue_event('gabelschalter_down')
#c.queue_event('call_accepted')
c . queue_event ( ' timeout ' )
c . queue_event ( ' call_ringing ' )
#c.queue_event('gabelschalter_down')
c . queue_event ( ' call_accepted ' )
c . queue_event ( ' call_ended ' )
c . queue_event ( ' timeout ' )
c . queue_event ( ' gabelschalter_down ' )
'''
except KeyboardInterrupt :
phone . stop ( )
feap . set_wecker ( False )
c . stop ( )
cfg = configreader . ConfigurationReader ( )
cfg . read ( ' fetap.ini ' )
phone = PhoneInterface ( cfg . phoneconfig )
feap = FeApUserInterface ( cfg . pinconfig )
c = StateMachineController ( phone , feap , cfg . dialconfig )
feap . add_gabelschalter_callback ( gabelschalter_cb )
feap . add_nummernschalter_active_callback ( nummernschalter_active_cb )
feap . add_nummernschalter_done_callback ( nummernschalter_done_cb )
phone . add_event_cb ( phone_cb )
phone . start ( )
try :
while True :
time . sleep ( 1 )
'''
c . queue_event ( ' gabelschalter_up ' )
c . queue_event ( ' nummernschalter_input ' , 4 )
c . queue_event ( ' nummernschalter_input ' , 2 )
#c.queue_event('gabelschalter_down')
#c.queue_event('call_accepted')
c . queue_event ( ' timeout ' )
c . queue_event ( ' call_ringing ' )
#c.queue_event('gabelschalter_down')
c . queue_event ( ' call_accepted ' )
c . queue_event ( ' call_ended ' )
c . queue_event ( ' timeout ' )
c . queue_event ( ' gabelschalter_down ' )
'''
except KeyboardInterrupt :
phone . stop ( )
feap . set_wecker ( False )
c . stop ( )