mirror of
https://github.com/naruxde/revpipyload.git
synced 2025-11-08 15:13:52 +01:00
Implement bytebuffer and length check to picontrolserver.py
Compatible to RevPiModIO <= 2.4.2
This commit is contained in:
@@ -184,7 +184,6 @@ class RevPiSlaveDev(Thread):
|
|||||||
"""Init RevPiSlaveDev-Class.
|
"""Init RevPiSlaveDev-Class.
|
||||||
|
|
||||||
@param devcon Tuple der Verbindung
|
@param devcon Tuple der Verbindung
|
||||||
@param deadtime Timeout der Vararbeitung
|
|
||||||
@param acl Berechtigungslevel
|
@param acl Berechtigungslevel
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -221,15 +220,27 @@ class RevPiSlaveDev(Thread):
|
|||||||
"can not open process image {0}".format(proginit.pargs.procimg)
|
"can not open process image {0}".format(proginit.pargs.procimg)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
buff_size = 2048
|
||||||
dirty = True
|
dirty = True
|
||||||
|
netcmd = bytearray()
|
||||||
|
buff_block = bytearray(buff_size)
|
||||||
|
buff_recv = bytearray()
|
||||||
while not self._evt_exit.is_set():
|
while not self._evt_exit.is_set():
|
||||||
# Laufzeitberechnung starten
|
# Laufzeitberechnung starten
|
||||||
ot = default_timer()
|
ot = default_timer()
|
||||||
|
netcmd.clear()
|
||||||
|
|
||||||
# Meldung erhalten
|
# Meldung erhalten
|
||||||
try:
|
try:
|
||||||
netcmd = self._devcon.recv(16)
|
recv_len = 16
|
||||||
except Exception:
|
while recv_len > 0:
|
||||||
|
count = self._devcon.recv_into(buff_block, recv_len)
|
||||||
|
if count == 0:
|
||||||
|
raise IOError("lost network connection")
|
||||||
|
netcmd += buff_block[:count]
|
||||||
|
recv_len -= count
|
||||||
|
except Exception as e:
|
||||||
|
proginit.logger.exception(e)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Wenn Meldung ungültig ist aussteigen
|
# Wenn Meldung ungültig ist aussteigen
|
||||||
@@ -261,7 +272,7 @@ class RevPiSlaveDev(Thread):
|
|||||||
|
|
||||||
# Berechtigung prüfen und ggf. trennen
|
# Berechtigung prüfen und ggf. trennen
|
||||||
if self._acl < 1:
|
if self._acl < 1:
|
||||||
self._devcon.send(b'\x18')
|
self._devcon.sendall(b'\x18')
|
||||||
break
|
break
|
||||||
|
|
||||||
position = int.from_bytes(netcmd[3:5], byteorder="little")
|
position = int.from_bytes(netcmd[3:5], byteorder="little")
|
||||||
@@ -270,33 +281,33 @@ class RevPiSlaveDev(Thread):
|
|||||||
|
|
||||||
if control == b'\x1d' and length > 0:
|
if control == b'\x1d' and length > 0:
|
||||||
# Empfange Datenblock zu schreiben nach Meldung
|
# Empfange Datenblock zu schreiben nach Meldung
|
||||||
|
buff_recv.clear()
|
||||||
try:
|
try:
|
||||||
block = self._devcon.recv(length)
|
while length > 0:
|
||||||
|
count = self._devcon.recv_into(buff_block, min(length, buff_size))
|
||||||
|
if count == 0:
|
||||||
|
raise IOError("lost network connection")
|
||||||
|
buff_recv += buff_block[:count]
|
||||||
|
length -= count
|
||||||
except Exception:
|
except Exception:
|
||||||
proginit.logger.error("error while recv data to write")
|
proginit.logger.error("error while recv data to write")
|
||||||
self._writeerror = True
|
self._writeerror = True
|
||||||
break
|
break
|
||||||
fh_proc.seek(position)
|
fh_proc.seek(position)
|
||||||
|
fh_proc.write(buff_recv)
|
||||||
# Länge der Daten prüfen
|
|
||||||
if len(block) == length:
|
|
||||||
fh_proc.write(block)
|
|
||||||
else:
|
|
||||||
proginit.logger.error("got wrong length to write")
|
|
||||||
break
|
|
||||||
|
|
||||||
# Record seperator character
|
# Record seperator character
|
||||||
if control == b'\x1c':
|
if control == b'\x1c':
|
||||||
# Bestätige Schreibvorgang aller Datenblöcke
|
# Bestätige Schreibvorgang aller Datenblöcke
|
||||||
if self._writeerror:
|
if self._writeerror:
|
||||||
self._devcon.send(b'\xff')
|
self._devcon.sendall(b'\xff')
|
||||||
else:
|
else:
|
||||||
self._devcon.send(b'\x1e')
|
self._devcon.sendall(b'\x1e')
|
||||||
self._writeerror = False
|
self._writeerror = False
|
||||||
|
|
||||||
elif cmd == b'\x06\x16':
|
elif cmd == b'\x06\x16':
|
||||||
# Just sync
|
# Just sync
|
||||||
self._devcon.send(b'\x06\x16')
|
self._devcon.sendall(b'\x06\x16')
|
||||||
|
|
||||||
elif cmd == b'CF':
|
elif cmd == b'CF':
|
||||||
# Socket konfigurieren
|
# Socket konfigurieren
|
||||||
@@ -316,10 +327,10 @@ class RevPiSlaveDev(Thread):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Record seperator character
|
# Record seperator character
|
||||||
self._devcon.send(b'\x1e')
|
self._devcon.sendall(b'\x1e')
|
||||||
else:
|
else:
|
||||||
proginit.logger.error("timeout value must be 0 to 65535")
|
proginit.logger.error("timeout value must be 0 to 65535")
|
||||||
self._devcon.send(b'\xff')
|
self._devcon.sendall(b'\xff')
|
||||||
break
|
break
|
||||||
|
|
||||||
elif cmd == b'EY':
|
elif cmd == b'EY':
|
||||||
@@ -328,7 +339,7 @@ class RevPiSlaveDev(Thread):
|
|||||||
|
|
||||||
# Berechtigung prüfen und ggf. trennen
|
# Berechtigung prüfen und ggf. trennen
|
||||||
if self._acl < 1:
|
if self._acl < 1:
|
||||||
self._devcon.send(b'\x18')
|
self._devcon.sendall(b'\x18')
|
||||||
break
|
break
|
||||||
|
|
||||||
position = int.from_bytes(netcmd[3:5], byteorder="little")
|
position = int.from_bytes(netcmd[3:5], byteorder="little")
|
||||||
@@ -342,7 +353,7 @@ class RevPiSlaveDev(Thread):
|
|||||||
self.ey_dict = {}
|
self.ey_dict = {}
|
||||||
|
|
||||||
# Record seperator character
|
# Record seperator character
|
||||||
self._devcon.send(ok_byte)
|
self._devcon.sendall(ok_byte)
|
||||||
proginit.logger.info("cleared all dirty bytes")
|
proginit.logger.info("cleared all dirty bytes")
|
||||||
|
|
||||||
elif control == b'\xfe':
|
elif control == b'\xfe':
|
||||||
@@ -352,7 +363,7 @@ class RevPiSlaveDev(Thread):
|
|||||||
del self.ey_dict[position]
|
del self.ey_dict[position]
|
||||||
|
|
||||||
# Record seperator character
|
# Record seperator character
|
||||||
self._devcon.send(ok_byte)
|
self._devcon.sendall(ok_byte)
|
||||||
proginit.logger.info(
|
proginit.logger.info(
|
||||||
"cleared dirty bytes on position {0}"
|
"cleared dirty bytes on position {0}"
|
||||||
"".format(position)
|
"".format(position)
|
||||||
@@ -360,28 +371,23 @@ class RevPiSlaveDev(Thread):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
# Dirtybytes hinzufügen
|
# Dirtybytes hinzufügen
|
||||||
bytesbuff = bytearray()
|
buff_recv.clear()
|
||||||
try:
|
try:
|
||||||
while not self._evt_exit.is_set() \
|
while length > 0:
|
||||||
and len(bytesbuff) < length:
|
count = self._devcon.recv_into(buff_block, min(length, buff_size))
|
||||||
block = self._devcon.recv(1024)
|
if count == 0:
|
||||||
bytesbuff += block
|
raise IOError("lost network connection")
|
||||||
if block == b'':
|
length -= count
|
||||||
break
|
buff_recv += buff_block[:count]
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
proginit.logger.error("error while recv dirty bytes")
|
proginit.logger.error("error while recv dirty bytes")
|
||||||
break
|
break
|
||||||
|
|
||||||
# Länge der Daten prüfen
|
self.ey_dict[position] = bytes(buff_recv)
|
||||||
if len(bytesbuff) == length:
|
|
||||||
self.ey_dict[position] = bytesbuff
|
|
||||||
else:
|
|
||||||
proginit.logger.error("got wrong length to write")
|
|
||||||
break
|
|
||||||
|
|
||||||
# Record seperator character
|
# Record seperator character
|
||||||
self._devcon.send(ok_byte)
|
self._devcon.sendall(ok_byte)
|
||||||
proginit.logger.info(
|
proginit.logger.info(
|
||||||
"got dirty bytes to write on error on position {0}"
|
"got dirty bytes to write on error on position {0}"
|
||||||
"".format(position)
|
"".format(position)
|
||||||
@@ -404,7 +410,7 @@ class RevPiSlaveDev(Thread):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# End-of-Transmission character immer senden
|
# End-of-Transmission character immer senden
|
||||||
self._devcon.send(b'\x04')
|
self._devcon.sendall(b'\x04')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
elif cmd == b'PH':
|
elif cmd == b'PH':
|
||||||
@@ -433,7 +439,7 @@ class RevPiSlaveDev(Thread):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# End-of-Transmission character immer senden
|
# End-of-Transmission character immer senden
|
||||||
self._devcon.send(b'\x04')
|
self._devcon.sendall(b'\x04')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
elif cmd == b'RH':
|
elif cmd == b'RH':
|
||||||
@@ -458,39 +464,49 @@ class RevPiSlaveDev(Thread):
|
|||||||
request = int.from_bytes(netcmd[3:7], byteorder="little")
|
request = int.from_bytes(netcmd[3:7], byteorder="little")
|
||||||
length = int.from_bytes(netcmd[7:9], byteorder="little")
|
length = int.from_bytes(netcmd[7:9], byteorder="little")
|
||||||
|
|
||||||
arg = self._devcon.recv(length)
|
buff_recv.clear()
|
||||||
|
try:
|
||||||
|
while length > 0:
|
||||||
|
count = self._devcon.recv_into(buff_block, min(length, buff_size))
|
||||||
|
if count == 0:
|
||||||
|
raise IOError("lost network connection")
|
||||||
|
length -= count
|
||||||
|
buff_recv += buff_block[:count]
|
||||||
|
except Exception:
|
||||||
|
proginit.logger.error("error on network ioctl call")
|
||||||
|
break
|
||||||
|
|
||||||
# Berechtigung prüfen und ggf. trennen
|
# Berechtigung prüfen und ggf. trennen
|
||||||
if self._acl < 1:
|
if self._acl < 1:
|
||||||
self._devcon.send(b'\x18')
|
self._devcon.sendall(b'\x18')
|
||||||
break
|
break
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if proginit.pargs.procimg == "/dev/piControl0":
|
if proginit.pargs.procimg == "/dev/piControl0":
|
||||||
# Läuft auf RevPi
|
# Läuft auf RevPi
|
||||||
ioctl(fh_proc, request, arg)
|
ioctl(fh_proc, request, bytes(buff_recv))
|
||||||
proginit.logger.debug(
|
proginit.logger.debug(
|
||||||
"ioctl {0} with {1} successful"
|
"ioctl {0} with {1} successful"
|
||||||
"".format(request, arg)
|
"".format(request, bytes(buff_recv))
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Simulation
|
# Simulation
|
||||||
# TODO: IOCTL für Dateien implementieren
|
# TODO: IOCTL für Dateien implementieren
|
||||||
proginit.logger.warning(
|
proginit.logger.warning(
|
||||||
"ioctl {0} with {1} simulated".format(request, arg)
|
"ioctl {0} with {1} simulated".format(request, bytes(buff_recv))
|
||||||
)
|
)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
proginit.logger.error(ex)
|
proginit.logger.error(ex)
|
||||||
self._devcon.send(b'\xff')
|
self._devcon.sendall(b'\xff')
|
||||||
else:
|
else:
|
||||||
self._devcon.send(b'\x1e')
|
self._devcon.sendall(b'\x1e')
|
||||||
|
|
||||||
elif proginit.pargs.developermode and cmd == b'DV':
|
elif proginit.pargs.developermode and cmd == b'DV':
|
||||||
# Development options
|
# Development options
|
||||||
# bCMc00000000000b = 16
|
# bCMc00000000000b = 16
|
||||||
if self._acl < 9:
|
if self._acl < 9:
|
||||||
# Spezieller ACL-Wert für Entwicklung
|
# Spezieller ACL-Wert für Entwicklung
|
||||||
self._devcon.send(b'\x18')
|
self._devcon.sendall(b'\x18')
|
||||||
break
|
break
|
||||||
|
|
||||||
c = netcmd[3:4]
|
c = netcmd[3:4]
|
||||||
@@ -498,7 +514,7 @@ class RevPiSlaveDev(Thread):
|
|||||||
# CMD a = Switch ACL to 0
|
# CMD a = Switch ACL to 0
|
||||||
self._acl = 0
|
self._acl = 0
|
||||||
proginit.logger.warning("DV: set acl to 0")
|
proginit.logger.warning("DV: set acl to 0")
|
||||||
self._devcon.send(b'\x1e')
|
self._devcon.sendall(b'\x1e')
|
||||||
elif c == b'b':
|
elif c == b'b':
|
||||||
# CMD b = Aktiviert/Deaktiviert den Fehlermodus
|
# CMD b = Aktiviert/Deaktiviert den Fehlermodus
|
||||||
if netcmd[4:5] == b'\x01':
|
if netcmd[4:5] == b'\x01':
|
||||||
@@ -507,7 +523,7 @@ class RevPiSlaveDev(Thread):
|
|||||||
else:
|
else:
|
||||||
self.__doerror = False
|
self.__doerror = False
|
||||||
proginit.logger.warning("DV: reset do_error")
|
proginit.logger.warning("DV: reset do_error")
|
||||||
self._devcon.send(b'\x1e')
|
self._devcon.sendall(b'\x1e')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Kein gültiges CMD gefunden, abbruch!
|
# Kein gültiges CMD gefunden, abbruch!
|
||||||
|
|||||||
Reference in New Issue
Block a user