From 7014712cef66e208a0d980393aff05b1872e53f6 Mon Sep 17 00:00:00 2001 From: Florian FRANK Date: Wed, 7 Sep 2022 18:41:29 +0200 Subject: [PATCH] Workaround for a non-standard vxi11 implementation of the RPC Reply to a GET PORT Call (PortMapper). Workaround for some equipment which do not set the last fragment bit to 1 for a RPC Reply to a GET PORT Call. Therefore the last fragment is asserted True only when the length of the received data matches the announced length, and the length of the payload corresponds to the length of such a Reply to GET PORT Call (28). The issue is described in https://groups.google.com/g/python-ivi/c/vxrdshKG43E/m/plOXFbsopUgJ?pli=1 The proposed workaround has been succesfully tested with equipment from Anritsu, namely the OSA models MS9740A and MS9740B. Signed-off-by: Florian FRANK --- vxi11/rpc.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/vxi11/rpc.py b/vxi11/rpc.py index 9d889a6..b631aa5 100644 --- a/vxi11/rpc.py +++ b/vxi11/rpc.py @@ -226,17 +226,35 @@ def sendrecord(sock, record): sendfrag(sock, 1, record) def recvfrag(sock): - header = sock.recv(4) + # constant length readout + # TODO could be variable via argument of recvfrag()-function + LEN = 1024 + header = sock.recv(LEN) if len(header) < 4: raise EOFError + # reading out the header x = struct.unpack(">I", header[0:4])[0] + # 32-bit masking of the header (4 * 8 bits) to get the RPC last fragment indicator last = ((x & 0x80000000) != 0) + # RPC field announcing the length of the payload (via masking) n = int(x & 0x7fffffff) - frag = bytearray() + # reading out the fragment + frag = bytearray( header[4:] ) + # waiting for the remaining fragments while len(frag) < n: buf = sock.recv(n - len(frag)) + # an empty read breaks the accumulating loop if not buf: raise EOFError + # accumulating the fragments frag.extend(buf) + + # below hack: some equipment do not set the last fragment bit to 1 + # for a RPC Reply to a GET PORT Call, so it is asserted True when + # the length of the received data matches the announced length + # the issue is described in https://groups.google.com/g/python-ivi/c/vxrdshKG43E/m/plOXFbsopUgJ?pli=1 + if len(frag)==n and n==28: + last=True + return last, frag def recvrecord(sock):