"""Read from the socket and parse complete messages"""
try:
segment = self.sock.recv(4096)
- except OSError:
+ except OSError as e:
log.warning(
"Reading from fd %d (IMEI %s): %s",
self.sock.fileno(),
)
self.buffer = self.buffer[framestart:]
# At this point, buffer starts with a packet
- frameend = self.buffer.find(b"\r\n", 4)
+ if len(self.buffer) < 6: # no len and proto - cannot proceed
+ break
+ exp_end = self.buffer[2] + 3 # Expect '\r\n' here
+ frameend = 0
+ # Length field can legitimeely be much less than the
+ # length of the packet (e.g. WiFi positioning), but
+ # it _should not_ be greater. Still sometimes it is.
+ # Luckily, not by too much: by maybe two or three bytes?
+ # Do this embarrassing hack to avoid accidental match
+ # of some binary data in the packet against '\r\n'.
+ while True:
+ frameend = self.buffer.find(b"\r\n", frameend)
+ if frameend >= (exp_end - 3): # Found realistic match
+ break
if frameend == -1: # Incomplete frame, return what we have
break
packet = self.buffer[2:frameend]
try:
msg = zpull.recv(zmq.NOBLOCK)
zmsg = Resp(msg)
- zpub.send(
- Bcast(
- is_incoming=False,
- proto=proto_of_message(zmsg.packet),
- imei=zmsg.imei,
- packet=zmsg.packet,
- ).packed
- )
tosend.append(zmsg)
except zmq.Again:
break
elif fl & zmq.POLLIN:
received = clients.recv(sk)
if received is None:
- log.debug(
- "Terminal gone from fd %d (IMEI %s)", sk, imei
- )
+ log.debug("Terminal gone from fd %d", sk)
tostop.append(sk)
else:
for imei, when, peeraddr, packet in received:
tostop.append(sk)
respmsg = inline_response(packet)
if respmsg is not None:
- clients.response(
- Resp(imei=imei, packet=respmsg)
+ tosend.append(
+ Resp(imei=imei, when=when, packet=respmsg)
)
else:
log.debug("Stray event: %s on socket %s", fl, sk)
poller.unregister(fd)
clients.stop(fd)
for zmsg in tosend:
+ zpub.send(
+ Bcast(
+ is_incoming=False,
+ proto=proto_of_message(zmsg.packet),
+ when=zmsg.when,
+ imei=zmsg.imei,
+ packet=zmsg.packet,
+ ).packed
+ )
log.debug("Sending to the client: %s", zmsg)
clients.response(zmsg)
for clntsock, clntaddr in topoll: