diff options
author | norly <ny-git@enpas.org> | 2018-12-16 23:05:33 +0100 |
---|---|---|
committer | norly <ny-git@enpas.org> | 2018-12-16 23:21:11 +0100 |
commit | f06df88629c6ae1205f522148102a0c3d04d1cf2 (patch) | |
tree | 1aa836591c2a9b34032150752218fb31e87562de /AEpy/AEMultipart.py | |
parent | 8fc49cd8badf6ceb6b6dfe03deb961cadf61839f (diff) |
Import first working version
Diffstat (limited to 'AEpy/AEMultipart.py')
-rw-r--r-- | AEpy/AEMultipart.py | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/AEpy/AEMultipart.py b/AEpy/AEMultipart.py new file mode 100644 index 0000000..a542bfa --- /dev/null +++ b/AEpy/AEMultipart.py @@ -0,0 +1,94 @@ +import struct + + + +def recvHeader(session): + (type, data) = session.recvMsg() + # TODO: Check for type 1, as that means an error. + # For example, a directory can't be listed because it doesn't exist. + assert type == 3 + assert len(data) == 8 + + (datalen, pktsize) = struct.unpack('!LL', data) + + return (datalen, pktsize) + + +def recvBlock(session): + # Send empty type 0 message to request next block + session.sendMsg(0, b'') + + (type, data) = session.recvMsg() + + if type == 1: + print('recvMultipartBlock: Host cancelled transfer.') + # Maybe TODO: Raise an exception + return (None, None) + + if type == 4: + # Last block + assert len(data) == 0 + return (None, None) + + # Expect a data block + assert type == 5 + + # Any data block has the offset prepended, + # followed by up to PACKETSIZE-4 bytes of payload. + assert len(data) >= 4 + + (offset,) = struct.unpack('!L', data[0:4]) + + return (offset, data[4:]) + + +def recv(session): + fullData = b'' + + (datalen, pktsize) = recvHeader(session) + + offset = 0 + data = b'' + while data != None: + assert offset == len(fullData) + fullData += data + + (offset, data) = recvBlock(session) + + return fullData + + +def send(session, fullData): + # Wait for Amiga to request first block with type 0 + (type, _) = session.recvMsg() + + # TODO: Handle transfer abort (type 1) + # TODO: What happens when sending an ADF != 901120 bytes? + assert (type == 0) or (type == 8) + + if type == 8: + # Does this confirm that we want to overwrite? + session.sendMsg(0, b'') + + # Send length and block size + session.sendMsg(3, struct.pack('!LL', len(fullData), session.packetsize)) + + bytesSent = 0 + while bytesSent < len(fullData): + # Wait for Amiga to request block with type 0 + (type, _) = session.recvMsg() + assert type == 0 + + print("AEMultipart.send: " + str(bytesSent)) + + txlen = min(session.packetsize - 4, len(fullData) - bytesSent) + session.sendMsg(5, struct.pack('!L', bytesSent) + fullData[bytesSent : bytesSent+txlen]) + + bytesSent += txlen + + # Wait for Amiga's type 0 + (type, _) = session.recvMsg() + assert type == 0 + + # Finish transfer + session.sendMsg(4, b'') |