5 def recvHeader(session):
6 (type, data) = session.recvMsg()
7 # TODO: Check for type 1, as that means an error.
8 # For example, a directory can't be listed because it doesn't exist.
12 (datalen, pktsize) = struct.unpack('!LL', data)
14 return (datalen, pktsize)
17 def recvBlock(session):
18 # Send empty type 0 message to request next block
19 session.sendMsg(0, b'')
21 (type, data) = session.recvMsg()
24 print('recvMultipartBlock: Host cancelled transfer.')
25 # Maybe TODO: Raise an exception
36 # Any data block has the offset prepended,
37 # followed by up to PACKETSIZE-4 bytes of payload.
40 (offset,) = struct.unpack('!L', data[0:4])
42 return (offset, data[4:])
48 (datalen, pktsize) = recvHeader(session)
53 assert offset == len(fullData)
56 (offset, data) = recvBlock(session)
61 def send(session, fullData):
62 # Wait for Amiga to request first block with type 0
63 (type, _) = session.recvMsg()
65 # TODO: Handle transfer abort (type 1)
66 # TODO: What happens when sending an ADF != 901120 bytes?
67 assert (type == 0) or (type == 8)
70 # Does this confirm that we want to overwrite?
71 session.sendMsg(0, b'')
73 # Send length and block size
74 session.sendMsg(3, struct.pack('!LL', len(fullData), session.packetsize))
77 while bytesSent < len(fullData):
78 # Wait for Amiga to request block with type 0
79 (type, _) = session.recvMsg()
82 print("AEMultipart.send: " + str(bytesSent))
84 txlen = min(session.packetsize - 4, len(fullData) - bytesSent)
85 session.sendMsg(5, struct.pack('!L', bytesSent) + fullData[bytesSent : bytesSent+txlen])
89 # Wait for Amiga's type 0
90 (type, _) = session.recvMsg()
94 session.sendMsg(4, b'')