Files
VA-Control-for-linux/reference/decompiled/d_ethernet.py
T
maikandClaude Opus 4.8 a7c93fa266 Erster Commit: nativer Linux-Port aus macOS-Bytecode
Läuft die Voice Acoustic VA-Remotecontrol (AllDSP AllControl) nativ unter Linux
auf echtem wxGTK 3.0 — ohne Wine und ohne dekompilierten App-Code. Ausgeführt wird
das unveränderte Python-2.7-Bytecode aus dem macOS-.app; C-Extensions (wxGTK/numpy/
scipy/PortAudio) kommen nativ aus Debian stretch.

Enthält: va/ (Original-.pyc + pure-Python-Libs + Assets + launch.py mit den drei
Linux-Fixes), Dockerfile/run.sh/entrypoint.sh, reference/ (dekompilierter Quellcode
zum Debuggen) und README/STATUS. img.cache (378 MB, regenerierbar) ist per
.gitignore ausgeschlossen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-20 19:57:01 +02:00

742 lines
26 KiB
Python

# uncompyle6 version 3.9.3
# Python bytecode version base 2.6 (62161)
# Decompiled from: Python 3.9.25 (main, Oct 31 2025, 23:16:49)
# [GCC 14.2.0]
# Embedded file name: d_ethernet.pyc
# Compiled at: 2025-03-06 16:07:19
import sys
from socket import *
import asyncore, asynchat, collections, mytime, threading, copy, struct, types, d_protocol, os.path, traceback, main, one_unit
from definitions import *
import d_protocol
def getString(str):
return one_unit.getString(str)
mac_names = 'posix'
if os.name in mac_names:
newline = '\n'
else:
newline = '\r\n'
usePolling = True
class Ethernet():
def __init__(self, parent):
self.thread1 = threading.Thread(name='AllDSP Server Ethernet Detection Port 50674', target=self.process1)
self.thread1.daemon = True
self.thread2 = threading.Thread(name='AllDSP Server Ethernet Detection Port 50774', target=self.process2)
self.thread2.daemon = True
if usePolling:
self.thread3 = threading.Thread(name='AllDSP Server Ethernet Polling', target=self.process3)
self.thread3.daemon = True
self.parent = parent
self.channel = None
self.conn = UDP_announce_listener(self)
self.polling_ip = 0
self.ip_index = 0
self.printedError = False
self.myip = None
self.found = []
self.foundtime = {}
one_unit.app.subnet_mask_list = {}
self.poll_skip_list = {}
self.pollingTimeout = 0.05
self.lastIPListCheckTime = 0
return
def add_unit(self, myip, pkt):
unit = d_protocol.RemoteUnit()
unit.MAC = pkt.MAC
unit.IP = myip
unit.type = pkt.broadcasted_skin
unit.name = 'No Name'
unit.pkt = pkt
unit.link_type = 'Ethernet'
unit.link_status = 'ready'
unit.HWVersion = pkt.HWVersion
unit.PICVersion = pkt.PICVersion
unit.Serial = pkt.Serial
unit.DSPState = pkt.DSPState
unit.ProductionDate = pkt.ProductionDate
unit.originalSwID = pkt.originalSwID
self.parent.peers.add(unit)
return
def sendResetLoader(self, s, ip):
try:
s.close()
except:
pass
mytime.sleep(0.1)
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(1)
s.connect((ip, 50675))
cmd = chr(0) + chr(7) + chr(0) + chr(0)
nul = '0' * 512
cmd += nul
try:
s.send(cmd)
print mytime.displayTime() + ' d_e.srl.Loader Reset 1 Sent to', ip
try:
pkt = s.recv(1024)
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
except:
print mytime.displayTime() + ' d_e.srl.No reply from', ip
except:
traceback.print_exc(file=sys.stdout)
s.close()
mytime.sleep(0.1)
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(1)
s.connect((ip, 50675))
cmd = chr(0) + 'Q'
nul = '0' * 512
cmd += nul
try:
s.send(cmd)
print mytime.displayTime() + ' d_e.srl.Loader Reset 2 Sent to', ip
try:
pkt = s.recv(1024)
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
except:
print mytime.displayTime() + ' d_e.srl.No reply from', ip
except:
traceback.print_exc(file=sys.stdout)
s.close()
mytime.sleep(0.1)
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(1)
s.connect((ip, 50675))
cmd = 'DDReset_Interface'
try:
s.send(cmd)
print mytime.displayTime() + ' d_e.srl.Loader Reset 3 Sent to', ip
try:
pkt = s.recv(1024)
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
except:
print mytime.displayTime() + ' d_e.srl.No reply from', ip
except:
traceback.print_exc(file=sys.stdout)
s.close()
mytime.sleep(0.1)
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(1)
s.connect((ip, 50675))
cmd = 'DDUPLOADFIRMWARE'
try:
s.send(cmd)
print mytime.displayTime() + ' d_e.srl.Loader Reset 4 Sent to', ip
try:
pkt = s.recv(1024)
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
except:
print mytime.displayTime() + ' d_e.srl.No reply from', ip
except:
traceback.print_exc(file=sys.stdout)
s.close()
mytime.sleep(0.1)
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(1)
s.connect((ip, 50675))
cmd = 'DCRESARTFIRMWARE'
try:
s.send(cmd)
print mytime.displayTime() + ' d_e.srl.Loader Reset 5 Sent to', ip
try:
pkt = s.recv(1024)
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
except:
print mytime.displayTime() + ' d_e.srl.No reply from', ip
except:
traceback.print_exc(file=sys.stdout)
s.close()
return
def pollIP(self, ip_to_poll):
try:
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(self.pollingTimeout)
s.connect((ip_to_poll, 50675))
s.settimeout(self.pollingTimeout)
try:
s.settimeout(1)
cmd = '4DPP' + chr(253) + chr(0) + chr(255) + chr(0)
cs = d_protocol.Checksum()
cs.add(cmd)
cmd += cs.get()
s.send(cmd)
try:
pkt = s.recv(1024)
except:
pkt = None
try:
self.sendResetLoader(s, ip_to_poll)
except:
pass
s.close()
return
else:
if pkt != None and len(pkt) > 3:
if pkt[:3] != 'DDB':
try:
pkt = s.recv(1024)
print mytime.displayTime(), 'd_e.pi.Got another packet'
mytime.sleep(0.01)
except:
pkt = None
s.close()
if pkt != None:
string = ''
for c in pkt:
string += ':' + hex(ord(c))
parsedPkt = parse_announce(pkt)
if isinstance(parsedPkt, Announcement):
if one_unit.app.runConnectionTest == True:
one_unit.app.connectionTestLog.write(mytime.displayTime() + ' Received solicited announcement, MAC: ' + parsedPkt.MAC + ', IP: ' + ip_to_poll + newline)
if parsedPkt.MAC not in one_unit.app.server.peers.ignore_list:
self.add_unit(ip_to_poll, parsedPkt)
self.found.append(ip_to_poll)
return True
self.foundtime[ip_to_poll] = mytime.clock()
else:
self.poll_skip_list[ip_to_poll] = mytime.clock()
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(1)
s.connect((ip_to_poll, 50675))
s.settimeout(1)
tmpcounter = 20
while tmpcounter > 0:
tmpcounter -= 1
try:
cmd = 'DDCOPY__FIRMWARE'
s.send(cmd)
mytime.sleep(0.1)
cmd = 'DQ'
s.send(cmd)
mytime.sleep(0.1)
except:
break
s.close()
else:
s.close()
except:
traceback.print_exc(file=sys.stdout)
except:
s.close()
return False
def getMyIPList(self):
self.lastIPListCheckTime = mytime.clock()
hostName = 'Start'
hostByName = 'Start'
try:
snm_list = {}
hostName = gethostname()
hostByName = gethostbyname_ex(hostName)
ip_list = [_[1] for ip in hostByName][2]
try:
one_unit.check_interfaces()
for adapter in one_unit.app.LAN_adapters.values():
if adapter.IPv4 is not None and adapter.IPv4 not in ip_list:
ip_list.append(adapter.IPv4)
if adapter.subnet_mask is not None:
snm_list[adapter.IPv4] = adapter.subnet_mask
except:
traceback.print_exc(file=sys.stdout)
if len(ip_list) == 0:
return []
if one_unit.app.my_ip_list != ip_list:
print mytime.displayTime() + ' My IP list changed from', one_unit.app.my_ip_list, 'to', ip_list
self.pollingTimeout = 0.01
one_unit.app.my_ip_list = ip_list
one_unit.app.subnet_mask_list = snm_list
one_unit.app.my_ip_list = ip_list
return
except:
if self.printedError == False:
print mytime.displayTime(), 'hostName:', hostName
print mytime.displayTime(), 'de.Could not make IP list, hostName:', hostName, 'error:'
traceback.print_exc(file=sys.stdout)
self.printedError = True
return
return
def ipToInt(self, ip):
try:
if ip.startswith('0x'):
return int(ip.replace('0x', ''), 16)
ip = ip.split('.')
res = int(ip[0]) << 24
res += int(ip[1]) << 16
res += int(ip[2]) << 8
if ip[3].find('(') > 0:
res += int(ip[3][:ip[3].find('(')]) << 0
else:
res += int(ip[3]) << 0
except:
print 'de.could not convert', ip[3], 'to int'
traceback.print_exc(file=sys.stdout)
res = 0
return res
def poll(self):
if self.myip == None:
self.getMyIPList()
if self.ip_index >= len(one_unit.app.my_ip_list):
self.ip_index = 0
if len(one_unit.app.my_ip_list) == 0:
mytime.sleep(0.1)
self.myip = None
else:
self.myip = one_unit.app.my_ip_list[self.ip_index].split('.')
return
else:
found = True
while found == True and one_unit.app.application_stopping == False:
found = False
if self.polling_ip > 255:
self.ip_index += 1
try:
if one_unit.app.my_ip_list[self.ip_index].find('169.254') >= 0 and len(one_unit.app.my_ip_list) > 1:
self.ip_index += 1
except:
pass
self.polling_ip = 0
self.getMyIPList()
if self.ip_index >= len(one_unit.app.my_ip_list):
self.ip_index = 0
if self.pollingTimeout >= 0.4 and len(one_unit.app.my_ip_list) > 0:
self.pollingTimeout = 0.05
if self.pollingTimeout < 0.5 and len(one_unit.app.my_ip_list) > 0:
self.pollingTimeout *= 2
if self.pollingTimeout > 0.4:
self.pollingTimeout = 0.4
if len(one_unit.app.my_ip_list) == 0:
mytime.sleep(0.1)
self.myip = None
else:
self.myip = one_unit.app.my_ip_list[self.ip_index].split('.')
if mytime.clock() - self.lastIPListCheckTime > 10:
self.getMyIPList()
if self.ip_index >= len(one_unit.app.my_ip_list):
self.ip_index = 0
if len(one_unit.app.my_ip_list) == 0:
mytime.sleep(0.1)
self.myip = None
else:
self.myip = one_unit.app.my_ip_list[self.ip_index].split('.')
if self.myip == None:
return
ip_to_poll = self.myip[0] + '.' + self.myip[1] + '.' + self.myip[2] + '.' + str(self.polling_ip)
self.polling_ip += 1
if ip_to_poll in self.poll_skip_list.keys():
if self.poll_skip_list[ip_to_poll] - mytime.clock() > 60:
found = True
continue
if ip_to_poll in self.foundtime.keys():
if mytime.clock() - self.foundtime[ip_to_poll] < 120:
found = True
continue
for testunit in self.parent.peers.units.values():
if testunit.IP == ip_to_poll and testunit.link_status != 'disconnected':
found = True
break
self.pollIP(ip_to_poll)
return
def process1(self):
try:
s_50674 = socket(AF_INET, SOCK_DGRAM)
s_50674.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
s_50674.bind(('0.0.0.0', 50674))
s_50674.settimeout(0.1)
self.Connected = False
self.socket_ok = True
except:
print mytime.displayTime() + ' de.Ethernet Server Failed'
traceback.print_exc(file=sys.stdout)
self.socket_ok = False
mytime.sleep(1)
if self.socket_ok == True:
print mytime.displayTime(), 'de.Ethernet Server Listening for incoming connections on port 50674'
while one_unit.app.application_stopping == False:
pkt = None
try:
(pkt, addr) = s_50674.recvfrom(1024)
if one_unit.app.runConnectionTest == True:
print mytime.displayTime(), 'Ethernet Server: got packet from 50674', addr, len(pkt)
except timeout:
pass
except:
traceback.print_exc(file=sys.stdout)
if pkt == None:
continue
subnetMatch = False
for ip in one_unit.app.my_ip_list:
if ip in one_unit.app.subnet_mask_list:
if self.ipToInt(ip) & self.ipToInt(one_unit.app.subnet_mask_list[ip]) == self.ipToInt(addr[0]) & self.ipToInt(one_unit.app.subnet_mask_list[ip]):
subnetMatch = True
elif addr[0][:addr[0].find('.')] == ip[:ip.find('.')]:
subnetMatch = True
if subnetMatch == False:
self.getMyIPList()
self.conn.handle_read(pkt, addr)
s_50674.close()
mytime.sleep(0.1)
print mytime.displayTime() + ' UDP Announce socket closed'
else:
print mytime.displayTime() + ' Ethernet Server Failed (Socket OK = False)'
return
def process2(self):
try:
s_50774 = socket(AF_INET, SOCK_DGRAM)
s_50774.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
s_50774.bind(('0.0.0.0', 50774))
s_50774.settimeout(0.1)
self.Connected = False
self.socket_ok = True
except:
print mytime.displayTime() + ' de.Ethernet Server Failed'
traceback.print_exc(file=sys.stdout)
self.socket_ok = False
mytime.sleep(1)
if self.socket_ok == True:
print mytime.displayTime(), 'de.Ethernet Server Listening for incoming connections on port 50774'
while one_unit.app.application_stopping == False:
pkt = None
try:
(pkt, addr) = s_50774.recvfrom(1024)
if one_unit.app.runConnectionTest == True:
print mytime.displayTime(), 'Ethernet Server: got packet from 50774 #######################################', addr, len(pkt)
except timeout:
pass
except:
traceback.print_exc(file=sys.stdout)
if pkt == None:
continue
subnetMatch = False
for ip in one_unit.app.my_ip_list:
if ip in one_unit.app.subnet_mask_list:
if self.ipToInt(ip) & self.ipToInt(one_unit.app.subnet_mask_list[ip]) == self.ipToInt(addr[0]) & self.ipToInt(one_unit.app.subnet_mask_list[ip]):
subnetMatch = True
elif addr[0][:addr[0].find('.')] == ip[:ip.find('.')]:
subnetMatch = True
if subnetMatch == False:
self.getMyIPList()
self.conn.handle_read(pkt, addr)
s_50774.close()
mytime.sleep(0.1)
print mytime.displayTime() + ' UDP Announce socket closed'
else:
print mytime.displayTime() + ' Ethernet Server Failed (Socket OK = False)'
return
def process3(self):
one_unit.lowPriority()
self.pollingTimeout = 0.5
loop = 30
while loop > 0 and one_unit.app.application_stopping == False:
try:
for mac in one_unit.app.knownIP:
if one_unit.app.application_stopping == True:
break
ip = one_unit.app.knownIP[mac]['IP']
if ip.lower().find('offline') >= 0:
continue
self.pollIP(ip)
break
except:
if loop < 5:
traceback.print_exc(file=sys.stdout)
mytime.sleep(0.1)
loop -= 1
self.pollingTimeout = 0.05
while one_unit.app.application_stopping == False:
try:
self.poll()
except:
traceback.print_exc(file=sys.stdout)
print mytime.displayTime() + ' TCP Polling Server closed'
return
def start(self):
"""Start the updating thread"""
self.stopping = False
self.thread1.start()
self.thread2.start()
if usePolling:
self.thread3.start()
return
class UDP_announce_listener():
"""Handle announcements from hardware units that they broadcast
over UDP. Can be used to discover new hardware units in the local
network.
"""
def __init__(self, parent):
self.Connected = False
self.ResetValues = False
self.last_peq_key = None
self.last_xover_key = None
self.values = {}
self.last_requested = -1
self.parent = parent
self.lock = threading.Lock()
self.stopping = False
self.broadcasted_skin = ''
self.last_hw_packet_id = 0
self.invalid_packet_counter = 0
self.DisconnectTime = mytime.clock()
self.ignoreList = []
return
def verifyIP(self, IP):
try:
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(3)
s.connect((IP, 50675))
s.close()
return True
except:
s.close()
return False
return
def handle_read(self, pkt, addr):
pkt = parse_packet(pkt)
if isinstance(pkt, Announcement):
if one_unit.app.runConnectionTest == True:
txt = mytime.displayTime() + ' Received unsolicited announcement, MAC: ' + pkt.MAC + ', IP: ' + addr[0] + newline
one_unit.app.connectionTestLog.write(txt)
print txt
if pkt.MAC in self.parent.parent.peers.units and self.parent.parent.peers.units[pkt.MAC].IP == addr[0] and self.parent.parent.peers.units[pkt.MAC].link_status in ('available',
'ready'):
if one_unit.app.runConnectionTest == True:
print mytime.displayTime() + ' d_e.hr.Ignoring connected unit', pkt.MAC, addr[0], self.parent.parent.peers.units[pkt.MAC].link_status
return
if pkt.MAC in one_unit.app.server.peers.ignore_list:
if one_unit.app.runConnectionTest == True:
print mytime.displayTime() + ' d_e.hr.Ignoring known ignored unit', pkt.MAC, addr[0]
return
unit = d_protocol.RemoteUnit()
unit.MK2 = pkt.MK2
unit.MAC = pkt.MAC
unit.IP = addr[0]
unit.type = pkt.broadcasted_skin
unit.name = 'No Name'
unit.pkt = pkt
unit.link_type = 'Ethernet'
try:
if True:
if one_unit.app.runConnectionTest == True:
print 'd_e.hr.2'
unit.link_status = 'ready'
except:
traceback.print_exc(file=sys.stdout)
else:
unit.HWVersion = pkt.HWVersion
unit.PICVersion = pkt.PICVersion
unit.Serial = pkt.Serial
unit.DSPState = pkt.DSPState
unit.ProductionDate = pkt.ProductionDate
unit.originalSwID = pkt.originalSwID
self.parent.parent.peers.add(unit)
return
class Announcement():
"""The announcement broadcast by hardware units over USB"""
def __init__(self):
"""Constructor"""
self.UnitType2 = None
self.UnitType1 = None
self.MAC = None
self.PC_PacketId = None
self.HW_PacketId = None
self.skin_high = None
self.skin_mid = None
self.originalSwID = ''
self.skin_low = None
self.broadcasted_skin = None
self.HWVersion = None
self.PICVersion = None
self.Serial = None
self.ProductionDate = None
self.DSPState = None
self.MK2 = False
return
def __str__(self):
return 'Announcement(%s, Type1=%s, Type2=%s)' % (self.MAC, self.UnitType1, self.UnitType2)
def parse_announce(data):
"""Parse the data sent by MakeConfigData(void) in DDEthernet.c,
line 537. This data can be found in UDP broadcasts and in TCP
responces to the 'J' command from the user.
"""
if len(data) < 42 or data[41] != 'Q':
return None
else:
if data[:3] != 'DDB':
return None
res = Announcement()
if data[36:42] == '67890Q':
res.MK2 = True
else:
res.MK2 = False
res.UnitType2 = ord(data[4])
res.UnitType1 = ord(data[5])
res.MAC = data[5:22]
res.PC_PacketID = ord(data[39])
res.HW_PacketID = ord(data[40])
res.skin_high = unicode(ord(data[33]))
res.skin_mid = unicode(ord(data[34]))
res.skin_low = unicode(ord(data[35]))
res.broadcasted_skin = res.skin_high + '_' + res.skin_mid + '_' + res.skin_low
skinBeforeReplacement = ':' + res.skin_high + '.' + res.skin_mid + '.' + res.skin_low
try:
res.broadcasted_skin = one_unit.app.type_replacements[res.broadcasted_skin]
except:
pass
try:
high = unicode(ord(data[22]))
mid = unicode(ord(data[23]))
low = unicode(ord(data[24]))
res.HWVersion = high + '.' + mid + '.' + low
high = unicode(ord(data[25]))
mid = unicode(ord(data[26]))
low = unicode(ord(data[27]))
res.PICVersion = high + '.' + mid + '.' + low
high = int(ord(data[28]))
mid = int(ord(data[29]))
low = int(ord(data[30]))
res.Serial = high * 65536 + mid * 256 + low
high = unicode(ord(data[36]))
mid = unicode(ord(data[37]))
low = unicode(ord(data[38]))
res.originalSwID = high + '.' + mid + '.' + low + skinBeforeReplacement
res.ProductionDate = '01-01-71'
except:
pass
res.DSPState = ord(data[37])
return res
def parse_packet(pkt):
buf = ''
while True:
chunk = pkt
if len(chunk) == 0:
return
buf += chunk
pos = buf.find('DD')
if pos < 0:
buf = ''
return
buf = buf[pos:]
if buf[41] != 'Q':
print mytime.displayTime() + ' Q not found'
buf = ''
return
while len(buf) < 42:
chunk = ser.read(42 - len(buf))
buf += chunk
pkt = None
if buf[:3] == 'DDB':
pkt = parse_announce(buf)
else:
print mytime.displayTime() + " Unknown pkt '%s'" % buf[:3]
return
buf = buf[42:]
return pkt
return
def makeMask(n):
"""return a mask of n bits as a long integer"""
return (2L << n - 1) - 1
def dottedQuadToNum(ip):
"""convert decimal dotted quad string to long integer"""
try:
inetaton = inet_aton(ip)
return struct.unpack('<L', inetaton)[0]
except:
traceback.print_exc(file=sys.stdout)
return 0
return
def networkMask(ip, bits):
"""Convert a network address to a long integer"""
return dottedQuadToNum(ip) & makeMask(bits)
def addressInNetwork(ip1, ip2, net):
if ip1.startswith('USB') or ip1.startswith('Startup'):
return True
try:
net = networkMask(net, 32)
ip1 = struct.unpack('<L', inet_aton(ip1))[0]
ip2 = struct.unpack('<L', inet_aton(ip2))[0]
return ip1 & net == ip2 & net
except:
print mytime.displayTime(), 'd_e.addressInNetwork failed', ip1, ip2, net
return
# okay decompiling pycode/d_ethernet.pyc