Skip to content
Snippets Groups Projects
Commit b2bb8e4e authored by Phil's avatar Phil
Browse files

Preliminary work on automata

parent ac4aaa16
No related branches found
No related tags found
No related merge requests found
...@@ -204,6 +204,7 @@ class Automaton: ...@@ -204,6 +204,7 @@ class Automaton:
__metaclass__ = Automaton_metaclass __metaclass__ = Automaton_metaclass
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
self.running = False
self.debug_level=0 self.debug_level=0
self.init_args=args self.init_args=args
self.init_kargs=kargs self.init_kargs=kargs
...@@ -247,7 +248,10 @@ class Automaton: ...@@ -247,7 +248,10 @@ class Automaton:
self.debug(2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname)) self.debug(2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname))
def run(self, *args, **kargs):
def start(self, *args, **kargs):
self.running = True
# Update default parameters # Update default parameters
a = args+self.init_args[len(args):] a = args+self.init_args[len(args):]
k = self.init_kargs k = self.init_kargs
...@@ -257,66 +261,91 @@ class Automaton: ...@@ -257,66 +261,91 @@ class Automaton:
# Start the automaton # Start the automaton
self.state=self.initial_states[0](self) self.state=self.initial_states[0](self)
self.send_sock = conf.L3socket() self.send_sock = conf.L3socket()
l = conf.L2listen(**self.socket_kargs) self.listen_sock = conf.L2listen(**self.socket_kargs)
self.packets = PacketList(name="session[%s]"%self.__class__.__name__) self.packets = PacketList(name="session[%s]"%self.__class__.__name__)
def next(self):
if not self.running:
self.start()
try:
self.debug(1, "## state=[%s]" % self.state.state)
# Entering a new state. First, call new state function
state_output = self.state.run()
if self.state.error:
self.running = False
raise self.ErrorState("Reached %s: [%r]" % (self.state.state, state_output), result=state_output)
if self.state.final:
self.running = False
raise StopIteration(state_output)
if state_output is None:
state_output = ()
elif type(state_output) is not list:
state_output = state_output,
# Then check immediate conditions
for cond in self.conditions[self.state.state]:
self.run_condition(cond, *state_output)
# If still there and no conditions left, we are stuck!
if ( len(self.recv_conditions[self.state.state]) == 0
and len(self.timeout[self.state.state]) == 1 ):
raise self.Stuck("stuck in [%s]" % self.state.state,result=state_output)
# Finally listen and pay attention to timeouts
expirations = iter(self.timeout[self.state.state])
next_timeout,timeout_func = expirations.next()
t0 = time.time()
while 1:
t = time.time()-t0
if next_timeout is not None:
if next_timeout <= t:
self.run_condition(timeout_func, *state_output)
next_timeout,timeout_func = expirations.next()
if next_timeout is None:
remain = None
else:
remain = next_timeout-t
r,_,_ = select([self.listen_sock],[],[],remain)
if self.listen_sock in r:
pkt = self.listen_sock.recv(MTU)
if pkt is not None:
if self.master_filter(pkt):
self.debug(3, "RECVD: %s" % pkt.summary())
for rcvcond in self.recv_conditions[self.state.state]:
self.run_condition(rcvcond, pkt, *state_output)
else:
self.debug(4, "FILTR: %s" % pkt.summary())
except ATMT.NewStateRequested,state_req:
self.debug(2, "switching from [%s] to [%s]" % (self.state.state,state_req.state))
self.state = state_req
return state_req
def run(self, *args, **kargs):
if not self.running:
self.start(*args, **kargs)
while 1: while 1:
try: try:
self.debug(1, "## state=[%s]" % self.state.state) self.next()
# Entering a new state. First, call new state function
state_output = self.state.run()
if self.state.error:
raise self.ErrorState("Reached %s: [%r]" % (self.state.state, state_output), result=state_output)
if self.state.final:
return state_output
if state_output is None:
state_output = ()
elif type(state_output) is not list:
state_output = state_output,
# Then check immediate conditions
for cond in self.conditions[self.state.state]:
self.run_condition(cond, *state_output)
# If still there and no conditions left, we are stuck!
if ( len(self.recv_conditions[self.state.state]) == 0
and len(self.timeout[self.state.state]) == 1 ):
raise self.Stuck("stuck in [%s]" % self.state.state,result=state_output)
# Finally listen and pay attention to timeouts
expirations = iter(self.timeout[self.state.state])
next_timeout,timeout_func = expirations.next()
t0 = time.time()
while 1:
t = time.time()-t0
if next_timeout is not None:
if next_timeout <= t:
self.run_condition(timeout_func, *state_output)
next_timeout,timeout_func = expirations.next()
if next_timeout is None:
remain = None
else:
remain = next_timeout-t
r,_,_ = select([l],[],[],remain)
if l in r:
pkt = l.recv(MTU)
if pkt is not None:
if self.master_filter(pkt):
self.debug(3, "RECVD: %s" % pkt.summary())
for rcvcond in self.recv_conditions[self.state.state]:
self.run_condition(rcvcond, pkt, *state_output)
else:
self.debug(4, "FILTR: %s" % pkt.summary())
except ATMT.NewStateRequested,state_req:
self.debug(2, "switching from [%s] to [%s]" % (self.state.state,state_req.state))
self.state = state_req
except KeyboardInterrupt: except KeyboardInterrupt:
self.debug(1,"Interrupted by user") self.debug(1,"Interrupted by user")
break break
except StopIteration,e:
return e.args[0]
cont = run
def __iter__(self):
if not self.running:
self.start()
return self
def my_send(self, pkt): def my_send(self, pkt):
self.send_sock.send(pkt) self.send_sock.send(pkt)
...@@ -326,5 +355,3 @@ class Automaton: ...@@ -326,5 +355,3 @@ class Automaton:
self.debug(3,"SENT : %s" % pkt.summary()) self.debug(3,"SENT : %s" % pkt.summary())
self.packets.append(pkt.copy()) self.packets.append(pkt.copy())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment