Mercurial > ~darius > hgwebdir.cgi > pyinst
comparison rsib.py @ 75:576f112e0aba
Fix read timeout handling so it works over imperfect links.
author | Daniel O'Connor <doconnor@gsoft.com.au> |
---|---|
date | Fri, 27 Sep 2024 09:27:33 +0930 |
parents | b6ebe05f250f |
children | 84f96c5fe791 |
comparison
equal
deleted
inserted
replaced
74:b6ebe05f250f | 75:576f112e0aba |
---|---|
80 MSG_HELLO = 0x40 # We send this on connect | 80 MSG_HELLO = 0x40 # We send this on connect |
81 MSG_CMD = 0x90 # Command to the instrument | 81 MSG_CMD = 0x90 # Command to the instrument |
82 MSG_SRQ = 0x91 # Query SRQ | 82 MSG_SRQ = 0x91 # Query SRQ |
83 | 83 |
84 import socket | 84 import socket |
85 import time | |
85 | 86 |
86 class RSIBDevice(object): | 87 class RSIBDevice(object): |
87 hello = '\x00\x00\x00\x40' | 88 hello = '\x00\x00\x00\x40' |
88 docmd = '\x00\x00\x00\x05\x90\x00\x01' | 89 docmd = '\x00\x00\x00\x05\x90\x00\x01' |
89 | 90 |
125 self.s1.send(msg) | 126 self.s1.send(msg) |
126 | 127 |
127 def read(self, timeout = 0.5): | 128 def read(self, timeout = 0.5): |
128 """Read data from the device, waits for up to timeout seconds for each TCP read""" | 129 """Read data from the device, waits for up to timeout seconds for each TCP read""" |
129 | 130 |
131 if timeout is not None: | |
132 timeout = time.clock_gettime(time.CLOCK_MONOTONIC) + timeout | |
130 self.s1.settimeout(timeout) | 133 self.s1.settimeout(timeout) |
131 | 134 |
132 reply = b'' | 135 reply = b'' |
133 last = False | 136 last = False |
134 while not last: | 137 while not last: |
135 # Fetch the header | 138 # Fetch the header |
136 rx = b'' | 139 hdr = b'' |
137 remain = 7 | 140 remain = 7 |
138 while len(rx) < 7: | 141 while len(hdr) < 7: |
139 rx = self.s1.recv(remain) | 142 rx = self.s1.recv(remain) |
140 if rx == b'': | 143 if len(rx) == 0: |
141 raise IOError("EOF from device") | 144 if timeout is not None and time.clock_gettime(time.CLOCK_MONOTONIC) >= timeout: |
145 raise IOError("EOF from device") | |
146 else: | |
147 time.sleep(0.1) | |
142 remain -= len(rx) | 148 remain -= len(rx) |
143 rxlen = rx[0] << 24 | rx[1] << 16 | rx[2] << 8 | rx[3] | 149 hdr += rx |
144 #print(rx, rxlen) | 150 rxlen = rx[0] << 24 | rx[1] << 16 | rx[2] << 8 | rx[3] |
145 if self.tag != rx[6]: | 151 #print(rx, rxlen) |
146 raise IOError("Reply out of order, got 0x%02x expected 0x%02x" % (rx[6], self.tag)) | 152 if self.tag != rx[6]: |
147 if rx[4] == 0x80: | 153 raise IOError("Reply out of order, got 0x%02x expected 0x%02x" % (rx[6], self.tag)) |
148 #print('EOM') | 154 if rx[4] == 0x80: |
149 last = True | 155 #print('EOM') |
150 if rx[5] != 0: | 156 last = True |
151 print("Mystery byte %d != 0" % (rx[5])) | 157 if rx[5] != 0: |
152 | 158 print("Mystery byte %d != 0" % (rx[5])) |
153 # Fetch the actual data block now we know the length | 159 |
154 remain = rxlen | 160 # Fetch the actual data block now we know the length |
155 while remain > 0: | 161 remain = rxlen |
156 rx = self.s1.recv(remain) | 162 while remain > 0: |
157 if rx == b'': | 163 rx = self.s1.recv(remain) |
164 if len(rx) == 0: | |
165 if timeout is not None and time.clock_gettime(time.CLOCK_MONOTONIC) >= timeout: | |
158 raise IOError("EOF from device") | 166 raise IOError("EOF from device") |
159 reply += rx | 167 else: |
160 remain -= len(rx) | 168 time.sleep(0.1) |
169 | |
170 reply += rx | |
171 remain -= len(rx) | |
161 | 172 |
162 return(reply) | 173 return(reply) |
163 | 174 |
164 def ask(self, s, timeout = None): | 175 def ask(self, s, timeout = None): |
165 '''Wrapper to send a command and wait for a reply''' | 176 '''Wrapper to send a command and wait for a reply''' |