7 def __init__(self, link):
15 rawHeader = self.link.recv(12)
16 if len(rawHeader) != 12:
17 print('recvMsg: len(rawHeader) == ' + str(len(rawHeader)) + ' data: ' + binascii.hexlify(rawHeader))
18 #assert len(rawHeader) == 12
20 (type, datalen, seq, crc) = struct.unpack('!HHLL', rawHeader)
21 assert crc == (binascii.crc32(rawHeader[0:8]) & 0xffffffff)
22 # TODO: Send PkRs if CRC mismatches
27 data = self.link.recv(datalen)
28 assert len(data) == datalen
30 # Note: Python calculates signed CRCs.
31 # Thus, we parse the incoming CRC as signed.
32 datacrc = self.link.recv(4)
33 assert len(datacrc) == 4
34 (datacrc,) = struct.unpack('!L', datacrc)
36 assert datacrc == (binascii.crc32(data) & 0xffffffff)
37 # TODO: Send PkRs if CRC mismatches
39 self.link.send(b'PkOk')
41 # seq is currently ignored when receiving
45 def sendMsg(self, type, data):
46 stream = struct.pack('!HHL', type, len(data), self.seq)
47 stream += struct.pack('!L', binascii.crc32(stream) & 0xffffffff)
51 stream += struct.pack('!L', binascii.crc32(data) & 0xffffffff)
53 self.link.send(stream)
55 # TODO: Re-send on 'PkRs'
56 assert self.link.recv(4) == b'PkOk'
63 self.sendMsg(2, b'Cloanto(r)')
64 # TBD: Password support.
65 # It is CRC32'd and the CRC is appended to the string above.
67 # TODO: Recover from desynced state
68 #if not self.isAcked():
70 # return self.sendInit()
72 (type, data) = self.recvMsg()
74 assert data.startswith(b'Cloanto')
80 self.sendMsg(0x6d, b'')
82 (type, data) = self.recvMsg()
84 if data != b'\0\0\0\0\0':
85 print('sendClose: data == ' + binascii.hexlify(data))
86 # Format of data returned:
90 # Byte 3: 00 - No error
91 # 06 - File no longer exists
92 # 1c - Timed out waiting for host to request next read block
93 # Byte 4: Path in case of error 06.
94 # Empty (null-terminated) otherwise?
95 # Null-terminated string.
96 #assert data == b'\0\0\0\0\0'