This can be useful for doing trial receptions of messages, and if they work, update the state when successful... Setting the state on the old object is best as it's hard to change all references to the new object.. copyof = strb.copy() try: copyof.recv_enc(msg) copyof.recv_mac(mac) except AuthenticationFailed: # failed, ignore message return else: # it worked strb.set_state_from(copyof) <process msg>mbed-sx1276
@@ -46,6 +46,12 @@ class Strobe(object): | |||||
def copy(self): return Strobe(None,copy_of=self) | def copy(self): return Strobe(None,copy_of=self) | ||||
def deepcopy(self): return self.copy() | def deepcopy(self): return self.copy() | ||||
def set_state_from(self, obj): | |||||
self.R,self.pos,self.posbegin,self.I0,self.F = \ | |||||
(obj.R,obj.pos,obj.posbegin,obj.I0, | |||||
obj.F.copy()) | |||||
self.st = bytearray(obj.st) | |||||
self.initialized = True | |||||
def _runF(self): | def _runF(self): | ||||
if self.initialized: | if self.initialized: | ||||
@@ -3,6 +3,7 @@ | |||||
import unittest | import unittest | ||||
from Strobe.Strobe import Strobe | from Strobe.Strobe import Strobe | ||||
from Strobe.Strobe import AuthenticationFailed | |||||
class TestCopy(unittest.TestCase): | class TestCopy(unittest.TestCase): | ||||
def test_copy(self): | def test_copy(self): | ||||
@@ -19,3 +20,20 @@ class TestCopy(unittest.TestCase): | |||||
# that both the original and copy work | # that both the original and copy work | ||||
self.assertEqual(b'anothertest', b.recv_enc(msg)) | self.assertEqual(b'anothertest', b.recv_enc(msg)) | ||||
self.assertEqual(b'anothertest', c.recv_enc(msg)) | self.assertEqual(b'anothertest', c.recv_enc(msg)) | ||||
def test_set_state_from(self): | |||||
a = Strobe(b'foo') | |||||
b = Strobe(b'foo') | |||||
c = b.copy() | |||||
mac = a.send_mac(8) | |||||
# That the wrong mac fails | |||||
with self.assertRaises(AuthenticationFailed): | |||||
b.recv_mac(b'random') | |||||
# but the state can be reset | |||||
b.set_state_from(c) | |||||
# and then works fine | |||||
b.recv_mac(mac) |