2017-02-24 02:11:07 +00:00
|
|
|
from __future__ import print_function, absolute_import, unicode_literals
|
2017-02-22 19:26:11 +00:00
|
|
|
import os
|
|
|
|
from zope.interface import implementer
|
2017-02-23 00:56:39 +00:00
|
|
|
from attr import attrs, attrib
|
|
|
|
from attr.validators import provides
|
2017-02-22 19:26:11 +00:00
|
|
|
from automat import MethodicalMachine
|
|
|
|
from . import _interfaces
|
|
|
|
from .wordlist import (byte_to_even_word, byte_to_odd_word,
|
|
|
|
#even_words_lowercase, odd_words_lowercase,
|
|
|
|
)
|
|
|
|
|
|
|
|
def make_code(nameplate, code_length):
|
|
|
|
assert isinstance(nameplate, type("")), type(nameplate)
|
|
|
|
words = []
|
|
|
|
for i in range(code_length):
|
|
|
|
# we start with an "odd word"
|
|
|
|
if i % 2 == 0:
|
|
|
|
words.append(byte_to_odd_word[os.urandom(1)].lower())
|
|
|
|
else:
|
|
|
|
words.append(byte_to_even_word[os.urandom(1)].lower())
|
|
|
|
return "%s-%s" % (nameplate, "-".join(words))
|
|
|
|
|
2017-02-23 00:56:39 +00:00
|
|
|
@attrs
|
2017-02-22 19:26:11 +00:00
|
|
|
@implementer(_interfaces.ICode)
|
|
|
|
class Code(object):
|
2017-02-23 00:56:39 +00:00
|
|
|
_timing = attrib(validator=provides(_interfaces.ITiming))
|
2017-02-22 19:26:11 +00:00
|
|
|
m = MethodicalMachine()
|
2017-03-02 03:55:13 +00:00
|
|
|
@m.setTrace()
|
2017-03-03 07:59:24 +00:00
|
|
|
def set_trace(): pass # pragma: no cover
|
2017-02-23 00:56:39 +00:00
|
|
|
|
2017-03-03 14:22:40 +00:00
|
|
|
def wire(self, boss, rendezvous_connector, lister):
|
2017-02-24 01:11:54 +00:00
|
|
|
self._B = _interfaces.IBoss(boss)
|
2017-02-22 19:26:11 +00:00
|
|
|
self._RC = _interfaces.IRendezvousConnector(rendezvous_connector)
|
2017-03-03 14:22:40 +00:00
|
|
|
self._L = _interfaces.ILister(lister)
|
2017-02-22 19:26:11 +00:00
|
|
|
|
|
|
|
@m.state(initial=True)
|
2017-03-04 11:40:19 +00:00
|
|
|
def S0A_unknown(self): pass # pragma: no cover
|
|
|
|
@m.state()
|
|
|
|
def S0B_unknown_connected(self): pass # pragma: no cover
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.state()
|
2017-03-03 07:59:24 +00:00
|
|
|
def S1A_connecting(self): pass # pragma: no cover
|
2017-02-24 01:11:54 +00:00
|
|
|
@m.state()
|
2017-03-03 07:59:24 +00:00
|
|
|
def S1B_allocating(self): pass # pragma: no cover
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.state()
|
2017-03-12 12:04:15 +00:00
|
|
|
def S2_input_nameplate(self): pass # pragma: no cover
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.state()
|
2017-03-12 12:04:15 +00:00
|
|
|
def S3_input_code_no_wordlist(self): pass # pragma: no cover
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.state()
|
2017-03-12 12:04:15 +00:00
|
|
|
def S4_input_code_wordlist(self): pass # pragma: no cover
|
2017-03-11 22:18:58 +00:00
|
|
|
@m.state()
|
|
|
|
def S5_known(self): pass # pragma: no cover
|
2017-02-22 19:26:11 +00:00
|
|
|
|
|
|
|
# from App
|
|
|
|
@m.input()
|
2017-02-24 02:23:55 +00:00
|
|
|
def allocate_code(self, code_length): pass
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
2017-03-11 09:03:24 +00:00
|
|
|
def input_code(self, input_helper): pass
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
2017-02-24 02:23:55 +00:00
|
|
|
def set_code(self, code): pass
|
2017-02-22 19:26:11 +00:00
|
|
|
|
|
|
|
# from RendezvousConnector
|
|
|
|
@m.input()
|
2017-02-24 01:11:54 +00:00
|
|
|
def connected(self): pass
|
|
|
|
@m.input()
|
|
|
|
def lost(self): pass
|
|
|
|
@m.input()
|
2017-02-22 19:26:11 +00:00
|
|
|
def rx_allocated(self, nameplate): pass
|
|
|
|
|
2017-03-03 14:22:40 +00:00
|
|
|
# from Lister
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
|
|
|
def got_nameplates(self, nameplates): pass
|
|
|
|
|
2017-03-11 22:18:58 +00:00
|
|
|
# from Nameplate
|
|
|
|
@m.input()
|
|
|
|
def got_wordlist(self, wordlist): pass
|
|
|
|
|
2017-03-12 17:38:48 +00:00
|
|
|
# from Input
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
2017-03-12 17:38:48 +00:00
|
|
|
def got_nameplate(self, nameplate): pass
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
2017-03-12 17:38:48 +00:00
|
|
|
def finished_input(self, code): pass
|
2017-02-22 19:26:11 +00:00
|
|
|
|
|
|
|
@m.output()
|
2017-03-03 14:22:40 +00:00
|
|
|
def L_refresh_nameplates(self):
|
|
|
|
self._L.refresh_nameplates()
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.output()
|
2017-03-11 09:03:24 +00:00
|
|
|
def start_input_and_L_refresh_nameplates(self, input_helper):
|
|
|
|
self._input_helper = input_helper
|
2017-03-03 14:22:40 +00:00
|
|
|
self._L.refresh_nameplates()
|
2017-02-23 00:56:39 +00:00
|
|
|
@m.output()
|
2017-03-04 11:40:19 +00:00
|
|
|
def stash_code_length_and_RC_tx_allocate(self, code_length):
|
|
|
|
self._code_length = code_length
|
|
|
|
self._RC.tx_allocate()
|
|
|
|
@m.output()
|
2017-02-24 01:11:54 +00:00
|
|
|
def stash_code_length(self, code_length):
|
2017-02-23 00:56:39 +00:00
|
|
|
self._code_length = code_length
|
2017-02-24 01:11:54 +00:00
|
|
|
@m.output()
|
|
|
|
def RC_tx_allocate(self):
|
2017-02-22 19:26:11 +00:00
|
|
|
self._RC.tx_allocate()
|
|
|
|
@m.output()
|
2017-03-11 22:18:58 +00:00
|
|
|
def stash_wordlist(self, wordlist):
|
|
|
|
# TODO
|
2017-02-22 19:26:11 +00:00
|
|
|
pass
|
|
|
|
@m.output()
|
|
|
|
def stash_nameplates(self, nameplates):
|
|
|
|
self._known_nameplates = nameplates
|
|
|
|
pass
|
|
|
|
@m.output()
|
|
|
|
def lookup_wordlist(self):
|
|
|
|
pass
|
|
|
|
@m.output()
|
|
|
|
def do_completion_code(self):
|
|
|
|
pass
|
|
|
|
@m.output()
|
2017-03-11 22:18:58 +00:00
|
|
|
def record_nameplate(self, nameplate):
|
|
|
|
self._nameplate = nameplate
|
|
|
|
@m.output()
|
|
|
|
def N_set_nameplate(self, nameplate):
|
|
|
|
self._N.set_nameplate(nameplate)
|
|
|
|
|
|
|
|
@m.output()
|
2017-02-24 01:11:54 +00:00
|
|
|
def generate_and_B_got_code(self, nameplate):
|
2017-02-22 19:26:11 +00:00
|
|
|
self._code = make_code(nameplate, self._code_length)
|
2017-02-24 01:11:54 +00:00
|
|
|
self._B_got_code()
|
2017-02-22 19:26:11 +00:00
|
|
|
|
2017-03-11 22:18:58 +00:00
|
|
|
@m.output()
|
|
|
|
def submit_words_and_B_got_code(self, words):
|
|
|
|
assert self._nameplate
|
|
|
|
self._code = self._nameplate + "-" + words
|
|
|
|
self._B_got_code()
|
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.output()
|
2017-02-24 01:11:54 +00:00
|
|
|
def B_got_code(self, code):
|
2017-02-22 19:26:11 +00:00
|
|
|
self._code = code
|
2017-02-24 01:11:54 +00:00
|
|
|
self._B_got_code()
|
2017-02-22 19:26:11 +00:00
|
|
|
|
2017-02-24 01:11:54 +00:00
|
|
|
def _B_got_code(self):
|
2017-03-12 17:38:48 +00:00
|
|
|
self._N.set_nameplate(nameplate) XXX
|
2017-02-24 01:11:54 +00:00
|
|
|
self._B.got_code(self._code)
|
2017-02-22 19:26:11 +00:00
|
|
|
|
2017-03-04 11:40:19 +00:00
|
|
|
S0A_unknown.upon(connected, enter=S0B_unknown_connected, outputs=[])
|
|
|
|
S0B_unknown_connected.upon(lost, enter=S0A_unknown, outputs=[])
|
|
|
|
|
2017-03-11 22:18:58 +00:00
|
|
|
S0A_unknown.upon(set_code, enter=S5_known, outputs=[B_got_code])
|
|
|
|
S0B_unknown_connected.upon(set_code, enter=S5_known, outputs=[B_got_code])
|
2017-02-22 19:26:11 +00:00
|
|
|
|
2017-03-04 11:40:19 +00:00
|
|
|
S0A_unknown.upon(allocate_code, enter=S1A_connecting,
|
|
|
|
outputs=[stash_code_length])
|
|
|
|
S0B_unknown_connected.upon(allocate_code, enter=S1B_allocating,
|
|
|
|
outputs=[stash_code_length_and_RC_tx_allocate])
|
2017-02-24 01:11:54 +00:00
|
|
|
S1A_connecting.upon(connected, enter=S1B_allocating,
|
|
|
|
outputs=[RC_tx_allocate])
|
|
|
|
S1B_allocating.upon(lost, enter=S1A_connecting, outputs=[])
|
2017-03-11 22:18:58 +00:00
|
|
|
S1B_allocating.upon(rx_allocated, enter=S5_known,
|
2017-02-24 01:11:54 +00:00
|
|
|
outputs=[generate_and_B_got_code])
|
2017-02-22 19:26:11 +00:00
|
|
|
|
2017-03-12 12:04:15 +00:00
|
|
|
S0A_unknown.upon(input_code, enter=S2_input_nameplate,
|
2017-03-04 11:40:19 +00:00
|
|
|
outputs=[start_input_and_L_refresh_nameplates])
|
2017-03-12 12:04:15 +00:00
|
|
|
S0B_unknown_connected.upon(input_code, enter=S2_input_nameplate,
|
2017-03-04 11:40:19 +00:00
|
|
|
outputs=[start_input_and_L_refresh_nameplates])
|
2017-03-12 12:04:15 +00:00
|
|
|
S2_input_nameplate.upon(update_nameplates, enter=S2_input_nameplate,
|
|
|
|
outputs=[L_refresh_nameplates])
|
|
|
|
S2_input_nameplate.upon(got_nameplates,
|
|
|
|
enter=S2_input_nameplate,
|
|
|
|
outputs=[stash_nameplates])
|
|
|
|
S2_input_nameplate.upon(claim_nameplate, enter=S3_input_code_no_wordlist,
|
|
|
|
outputs=[record_nameplate, N_set_nameplate])
|
|
|
|
S2_input_nameplate.upon(connected, enter=S2_input_nameplate, outputs=[])
|
|
|
|
S2_input_nameplate.upon(lost, enter=S2_input_nameplate, outputs=[])
|
|
|
|
|
|
|
|
S3_input_code_no_wordlist.upon(got_wordlist,
|
|
|
|
enter=S4_input_code_wordlist,
|
|
|
|
outputs=[stash_wordlist])
|
|
|
|
S3_input_code_no_wordlist.upon(submit_words, enter=S5_known,
|
|
|
|
outputs=[submit_words_and_B_got_code])
|
|
|
|
S3_input_code_no_wordlist.upon(connected, enter=S3_input_code_no_wordlist,
|
|
|
|
outputs=[])
|
|
|
|
S3_input_code_no_wordlist.upon(lost, enter=S3_input_code_no_wordlist,
|
|
|
|
outputs=[])
|
|
|
|
|
|
|
|
S4_input_code_wordlist.upon(submit_words, enter=S5_known,
|
|
|
|
outputs=[submit_words_and_B_got_code])
|
|
|
|
S4_input_code_wordlist.upon(connected, enter=S4_input_code_wordlist,
|
|
|
|
outputs=[])
|
|
|
|
S4_input_code_wordlist.upon(lost, enter=S4_input_code_wordlist,
|
|
|
|
outputs=[])
|
2017-03-11 22:18:58 +00:00
|
|
|
|
|
|
|
S5_known.upon(connected, enter=S5_known, outputs=[])
|
|
|
|
S5_known.upon(lost, enter=S5_known, outputs=[])
|